Move name
field from AssocItem
to AssocKind
variants.
To accurately reflect that RPITIT assoc items don't have a name. This avoids the use of `kw::Empty` to mean "no name", which is error prone. Helps with #137978.
This commit is contained in:
parent
89e93a51c8
commit
78599d83e7
43 changed files with 276 additions and 231 deletions
|
@ -443,7 +443,7 @@ fn best_definition_site_of_opaque<'tcx>(
|
||||||
let impl_def_id = tcx.local_parent(parent);
|
let impl_def_id = tcx.local_parent(parent);
|
||||||
for assoc in tcx.associated_items(impl_def_id).in_definition_order() {
|
for assoc in tcx.associated_items(impl_def_id).in_definition_order() {
|
||||||
match assoc.kind {
|
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())
|
if let ControlFlow::Break(span) = locator.check(assoc.def_id.expect_local())
|
||||||
{
|
{
|
||||||
return Some(span);
|
return Some(span);
|
||||||
|
@ -952,7 +952,7 @@ fn check_impl_items_against_trait<'tcx>(
|
||||||
.instantiate_identity(),
|
.instantiate_identity(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
ty::AssocKind::Const => {}
|
ty::AssocKind::Const { .. } => {}
|
||||||
ty::AssocKind::Type { .. } => {}
|
ty::AssocKind::Type { .. } => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,9 @@ pub(super) fn compare_impl_item(
|
||||||
match impl_item.kind {
|
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::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::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,
|
cause.span,
|
||||||
E0053,
|
E0053,
|
||||||
"method `{}` has an incompatible return type for trait",
|
"method `{}` has an incompatible return type for trait",
|
||||||
trait_m.name
|
trait_m.name()
|
||||||
);
|
);
|
||||||
infcx.err_ctxt().note_type_err(
|
infcx.err_ctxt().note_type_err(
|
||||||
&mut diag,
|
&mut diag,
|
||||||
|
@ -1032,7 +1034,7 @@ fn report_trait_method_mismatch<'tcx>(
|
||||||
impl_err_span,
|
impl_err_span,
|
||||||
E0053,
|
E0053,
|
||||||
"method `{}` has an incompatible type for trait",
|
"method `{}` has an incompatible type for trait",
|
||||||
trait_m.name
|
trait_m.name()
|
||||||
);
|
);
|
||||||
match &terr {
|
match &terr {
|
||||||
TypeError::ArgumentMutability(0) | TypeError::ArgumentSorts(_, 0)
|
TypeError::ArgumentMutability(0) | TypeError::ArgumentSorts(_, 0)
|
||||||
|
@ -1266,14 +1268,14 @@ fn compare_self_type<'tcx>(
|
||||||
impl_m_span,
|
impl_m_span,
|
||||||
E0185,
|
E0185,
|
||||||
"method `{}` has a `{}` declaration in the impl, but not in the trait",
|
"method `{}` has a `{}` declaration in the impl, but not in the trait",
|
||||||
trait_m.name,
|
trait_m.name(),
|
||||||
self_descr
|
self_descr
|
||||||
);
|
);
|
||||||
err.span_label(impl_m_span, format!("`{self_descr}` used in impl"));
|
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) {
|
if let Some(span) = tcx.hir_span_if_local(trait_m.def_id) {
|
||||||
err.span_label(span, format!("trait method declared without `{self_descr}`"));
|
err.span_label(span, format!("trait method declared without `{self_descr}`"));
|
||||||
} else {
|
} 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));
|
return Err(err.emit_unless(delay));
|
||||||
}
|
}
|
||||||
|
@ -1286,14 +1288,14 @@ fn compare_self_type<'tcx>(
|
||||||
impl_m_span,
|
impl_m_span,
|
||||||
E0186,
|
E0186,
|
||||||
"method `{}` has a `{}` declaration in the trait, but not in the impl",
|
"method `{}` has a `{}` declaration in the trait, but not in the impl",
|
||||||
trait_m.name,
|
trait_m.name(),
|
||||||
self_descr
|
self_descr
|
||||||
);
|
);
|
||||||
err.span_label(impl_m_span, format!("expected `{self_descr}` in impl"));
|
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) {
|
if let Some(span) = tcx.hir_span_if_local(trait_m.def_id) {
|
||||||
err.span_label(span, format!("`{self_descr}` used in trait"));
|
err.span_label(span, format!("`{self_descr}` used in trait"));
|
||||||
} else {
|
} 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));
|
return Err(err.emit_unless(delay));
|
||||||
|
@ -1421,7 +1423,7 @@ fn compare_number_of_generics<'tcx>(
|
||||||
"{} `{}` has {} {kind} parameter{} but its trait \
|
"{} `{}` has {} {kind} parameter{} but its trait \
|
||||||
declaration has {} {kind} parameter{}",
|
declaration has {} {kind} parameter{}",
|
||||||
item_kind,
|
item_kind,
|
||||||
trait_.name,
|
trait_.name(),
|
||||||
impl_count,
|
impl_count,
|
||||||
pluralize!(impl_count),
|
pluralize!(impl_count),
|
||||||
trait_count,
|
trait_count,
|
||||||
|
@ -1512,7 +1514,7 @@ fn compare_number_of_method_arguments<'tcx>(
|
||||||
impl_span,
|
impl_span,
|
||||||
E0050,
|
E0050,
|
||||||
"method `{}` has {} but the declaration in trait `{}` has {}",
|
"method `{}` has {} but the declaration in trait `{}` has {}",
|
||||||
trait_m.name,
|
trait_m.name(),
|
||||||
potentially_plural_count(impl_number_args, "parameter"),
|
potentially_plural_count(impl_number_args, "parameter"),
|
||||||
tcx.def_path_str(trait_m.def_id),
|
tcx.def_path_str(trait_m.def_id),
|
||||||
trait_number_args
|
trait_number_args
|
||||||
|
@ -1527,7 +1529,7 @@ fn compare_number_of_method_arguments<'tcx>(
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} 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(
|
err.span_label(
|
||||||
|
@ -1581,7 +1583,7 @@ fn compare_synthetic_generics<'tcx>(
|
||||||
impl_span,
|
impl_span,
|
||||||
E0643,
|
E0643,
|
||||||
"method `{}` has incompatible signature for trait",
|
"method `{}` has incompatible signature for trait",
|
||||||
trait_m.name
|
trait_m.name()
|
||||||
);
|
);
|
||||||
err.span_label(trait_span, "declaration in trait here");
|
err.span_label(trait_span, "declaration in trait here");
|
||||||
if impl_synthetic {
|
if impl_synthetic {
|
||||||
|
@ -1741,7 +1743,7 @@ fn compare_generic_param_kinds<'tcx>(
|
||||||
E0053,
|
E0053,
|
||||||
"{} `{}` has an incompatible generic parameter for trait `{}`",
|
"{} `{}` has an incompatible generic parameter for trait `{}`",
|
||||||
impl_item.descr(),
|
impl_item.descr(),
|
||||||
trait_item.name,
|
trait_item.name(),
|
||||||
&tcx.def_path_str(tcx.parent(trait_item.def_id))
|
&tcx.def_path_str(tcx.parent(trait_item.def_id))
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1877,7 +1879,7 @@ fn compare_const_predicate_entailment<'tcx>(
|
||||||
cause.span,
|
cause.span,
|
||||||
E0326,
|
E0326,
|
||||||
"implemented const `{}` has an incompatible type for trait",
|
"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| {
|
let trait_c_span = trait_ct.def_id.as_local().map(|trait_ct_def_id| {
|
||||||
|
@ -2237,8 +2239,8 @@ fn param_env_with_gat_bounds<'tcx>(
|
||||||
// bounds about themselves.
|
// bounds about themselves.
|
||||||
let impl_tys_to_install = match impl_ty.kind {
|
let impl_tys_to_install = match impl_ty.kind {
|
||||||
ty::AssocKind::Type {
|
ty::AssocKind::Type {
|
||||||
opt_rpitit_info:
|
data:
|
||||||
Some(
|
ty::AssocTypeData::Rpitit(
|
||||||
ty::ImplTraitInTraitData::Impl { fn_def_id }
|
ty::ImplTraitInTraitData::Impl { fn_def_id }
|
||||||
| ty::ImplTraitInTraitData::Trait { fn_def_id, .. },
|
| ty::ImplTraitInTraitData::Trait { fn_def_id, .. },
|
||||||
),
|
),
|
||||||
|
|
|
@ -205,7 +205,7 @@ fn missing_items_err(
|
||||||
|
|
||||||
let missing_items_msg = missing_items
|
let missing_items_msg = missing_items
|
||||||
.clone()
|
.clone()
|
||||||
.map(|trait_item| trait_item.name.to_string())
|
.map(|trait_item| trait_item.name().to_string())
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.join("`, `");
|
.join("`, `");
|
||||||
|
|
||||||
|
@ -236,7 +236,7 @@ fn missing_items_err(
|
||||||
let code = format!("{padding}{snippet}\n{padding}");
|
let code = format!("{padding}{snippet}\n{padding}");
|
||||||
if let Some(span) = tcx.hir_span_if_local(trait_item.def_id) {
|
if let Some(span) = tcx.hir_span_if_local(trait_item.def_id) {
|
||||||
missing_trait_item_label
|
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 {
|
missing_trait_item.push(errors::MissingTraitItemSuggestion {
|
||||||
span: sugg_sp,
|
span: sugg_sp,
|
||||||
code,
|
code,
|
||||||
|
@ -504,9 +504,9 @@ fn suggestion_signature<'tcx>(
|
||||||
tcx,
|
tcx,
|
||||||
tcx.predicates_of(assoc.def_id).instantiate_own(tcx, args),
|
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 ty = tcx.type_of(assoc.def_id).instantiate_identity();
|
||||||
let val = tcx
|
let val = tcx
|
||||||
.infer_ctxt()
|
.infer_ctxt()
|
||||||
|
@ -514,7 +514,7 @@ fn suggestion_signature<'tcx>(
|
||||||
.err_ctxt()
|
.err_ctxt()
|
||||||
.ty_kind_suggestion(tcx.param_env(assoc.def_id), ty)
|
.ty_kind_suggestion(tcx.param_env(assoc.def_id), ty)
|
||||||
.unwrap_or_else(|| "value".to_string());
|
.unwrap_or_else(|| "value".to_string());
|
||||||
format!("const {}: {} = {};", assoc.name, ty, val)
|
format!("const {}: {} = {};", name, ty, val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -474,7 +474,7 @@ fn check_gat_where_clauses(tcx: TyCtxt<'_>, trait_def_id: LocalDefId) {
|
||||||
gat_generics,
|
gat_generics,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ty::AssocKind::Const => None,
|
ty::AssocKind::Const { .. } => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(item_required_bounds) = item_required_bounds {
|
if let Some(item_required_bounds) = item_required_bounds {
|
||||||
|
@ -1076,7 +1076,7 @@ fn check_associated_item(
|
||||||
};
|
};
|
||||||
|
|
||||||
match item.kind {
|
match item.kind {
|
||||||
ty::AssocKind::Const => {
|
ty::AssocKind::Const { .. } => {
|
||||||
let ty = tcx.type_of(item.def_id).instantiate_identity();
|
let ty = tcx.type_of(item.def_id).instantiate_identity();
|
||||||
let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty);
|
let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty);
|
||||||
wfcx.register_wf_obligation(span, loc, ty.into());
|
wfcx.register_wf_obligation(span, loc, ty.into());
|
||||||
|
|
|
@ -51,7 +51,7 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
|
||||||
|
|
||||||
for &item1 in impl_items1.in_definition_order() {
|
for &item1 in impl_items1.in_definition_order() {
|
||||||
let collision = impl_items2
|
let collision = impl_items2
|
||||||
.filter_by_name_unhygienic(item1.name)
|
.filter_by_name_unhygienic(item1.name())
|
||||||
.any(|&item2| self.compare_hygienically(item1, item2));
|
.any(|&item2| self.compare_hygienically(item1, item2));
|
||||||
|
|
||||||
if collision {
|
if collision {
|
||||||
|
@ -113,7 +113,7 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
|
||||||
let mut res = Ok(());
|
let mut res = Ok(());
|
||||||
for &item1 in impl_items1.in_definition_order() {
|
for &item1 in impl_items1.in_definition_order() {
|
||||||
let collision = impl_items2
|
let collision = impl_items2
|
||||||
.filter_by_name_unhygienic(item1.name)
|
.filter_by_name_unhygienic(item1.name())
|
||||||
.find(|&&item2| self.compare_hygienically(item1, item2));
|
.find(|&&item2| self.compare_hygienically(item1, item2));
|
||||||
|
|
||||||
if let Some(item2) = collision {
|
if let Some(item2) = collision {
|
||||||
|
@ -230,11 +230,11 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
|
||||||
let mut ids = impl_items
|
let mut ids = impl_items
|
||||||
.in_definition_order()
|
.in_definition_order()
|
||||||
.filter_map(|item| {
|
.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 {
|
if let IndexEntry::Occupied(e) = &entry {
|
||||||
Some(*e.get())
|
Some(*e.get())
|
||||||
} else {
|
} else {
|
||||||
idents_to_add.push(item.name);
|
idents_to_add.push(item.name());
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -32,7 +32,7 @@ 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) {
|
for &assoc_id in tcx.associated_item_def_ids(impl_def_id) {
|
||||||
let assoc = tcx.associated_item(assoc_id);
|
let assoc = tcx.associated_item(assoc_id);
|
||||||
match assoc.kind {
|
match assoc.kind {
|
||||||
ty::AssocKind::Const | ty::AssocKind::Fn { .. } => {
|
ty::AssocKind::Const { .. } | ty::AssocKind::Fn { .. } => {
|
||||||
locator.check(assoc_id.expect_local())
|
locator.check(assoc_id.expect_local())
|
||||||
}
|
}
|
||||||
// Associated types don't have bodies, so they can't constrain hidden types
|
// Associated types don't have bodies, so they can't constrain hidden types
|
||||||
|
|
|
@ -492,7 +492,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
|
||||||
.gen_args
|
.gen_args
|
||||||
.constraints
|
.constraints
|
||||||
.iter()
|
.iter()
|
||||||
.any(|constraint| constraint.ident.name == item.name)
|
.any(|constraint| constraint.ident.name == item.name())
|
||||||
})
|
})
|
||||||
.filter(|item| !item.is_impl_trait_in_trait())
|
.filter(|item| !item.is_impl_trait_in_trait())
|
||||||
.map(|item| self.tcx.item_ident(item.def_id).to_string())
|
.map(|item| self.tcx.item_ident(item.def_id).to_string())
|
||||||
|
|
|
@ -168,7 +168,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
let all_candidate_names: Vec<_> = all_candidates()
|
let all_candidate_names: Vec<_> = all_candidates()
|
||||||
.flat_map(|r| tcx.associated_items(r.def_id()).in_definition_order())
|
.flat_map(|r| tcx.associated_items(r.def_id()).in_definition_order())
|
||||||
.filter_map(|item| {
|
.filter_map(|item| {
|
||||||
(!item.is_impl_trait_in_trait() && item.as_tag() == assoc_tag).then_some(item.name)
|
if !item.is_impl_trait_in_trait() && item.as_tag() == assoc_tag {
|
||||||
|
item.opt_name()
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
@ -200,7 +204,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|trait_def_id| tcx.associated_items(*trait_def_id).in_definition_order())
|
.flat_map(|trait_def_id| tcx.associated_items(*trait_def_id).in_definition_order())
|
||||||
.filter_map(|item| {
|
.filter_map(|item| {
|
||||||
(!item.is_impl_trait_in_trait() && item.as_tag() == assoc_tag).then_some(item.name)
|
(!item.is_impl_trait_in_trait() && item.as_tag() == assoc_tag)
|
||||||
|
.then_some(item.name())
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
@ -337,7 +342,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
) -> ErrorGuaranteed {
|
) -> ErrorGuaranteed {
|
||||||
let tcx = self.tcx();
|
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 Some(constraint) = constraint
|
||||||
&& let hir::AssocItemConstraintKind::Bound { .. } = constraint.kind
|
&& let hir::AssocItemConstraintKind::Bound { .. } = constraint.kind
|
||||||
{
|
{
|
||||||
|
@ -761,7 +766,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
// `issue-22560.rs`.
|
// `issue-22560.rs`.
|
||||||
let mut dyn_compatibility_violations = Ok(());
|
let mut dyn_compatibility_violations = Ok(());
|
||||||
for (assoc_item, trait_ref) in &missing_assoc_types {
|
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;
|
names_len += 1;
|
||||||
|
|
||||||
let violations =
|
let violations =
|
||||||
|
@ -852,16 +857,17 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
let mut names: UnordMap<_, usize> = Default::default();
|
let mut names: UnordMap<_, usize> = Default::default();
|
||||||
for (item, _) in &missing_assoc_types {
|
for (item, _) in &missing_assoc_types {
|
||||||
types_count += 1;
|
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 dupes = false;
|
||||||
let mut shadows = false;
|
let mut shadows = false;
|
||||||
for (item, trait_ref) in &missing_assoc_types {
|
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();
|
let trait_def_id = trait_ref.def_id();
|
||||||
dupes = true;
|
dupes = true;
|
||||||
format!("{}::", tcx.def_path_str(trait_def_id))
|
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();
|
let trait_def_id = trait_ref.def_id();
|
||||||
shadows = true;
|
shadows = true;
|
||||||
format!("{}::", tcx.def_path_str(trait_def_id))
|
format!("{}::", tcx.def_path_str(trait_def_id))
|
||||||
|
@ -871,7 +877,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
|
|
||||||
let mut is_shadowed = false;
|
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
|
&& *assoc_item != item
|
||||||
{
|
{
|
||||||
is_shadowed = true;
|
is_shadowed = true;
|
||||||
|
@ -880,17 +886,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
if assoc_item.def_id.is_local() { ", consider renaming it" } else { "" };
|
if assoc_item.def_id.is_local() { ", consider renaming it" } else { "" };
|
||||||
err.span_label(
|
err.span_label(
|
||||||
tcx.def_span(assoc_item.def_id),
|
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 { "" };
|
let rename_message = if is_shadowed { ", consider renaming it" } else { "" };
|
||||||
|
|
||||||
if let Some(sp) = tcx.hir_span_if_local(item.def_id) {
|
if let Some(sp) = tcx.hir_span_if_local(item.def_id) {
|
||||||
err.span_label(
|
err.span_label(sp, format!("`{}{}` defined here{}", prefix, name, rename_message));
|
||||||
sp,
|
|
||||||
format!("`{}{}` defined here{}", prefix, item.name, rename_message),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if potential_assoc_types.len() == missing_assoc_types.len() {
|
if potential_assoc_types.len() == missing_assoc_types.len() {
|
||||||
|
@ -903,7 +906,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
{
|
{
|
||||||
let types: Vec<_> = missing_assoc_types
|
let types: Vec<_> = missing_assoc_types
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(item, _)| format!("{} = Type", item.name))
|
.map(|(item, _)| format!("{} = Type", item.name()))
|
||||||
.collect();
|
.collect();
|
||||||
let code = if let Some(snippet) = snippet.strip_suffix('>') {
|
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
|
// 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();
|
let mut names: FxIndexMap<_, usize> = FxIndexMap::default();
|
||||||
for (item, _) in &missing_assoc_types {
|
for (item, _) in &missing_assoc_types {
|
||||||
types_count += 1;
|
types_count += 1;
|
||||||
*names.entry(item.name).or_insert(0) += 1;
|
*names.entry(item.name()).or_insert(0) += 1;
|
||||||
}
|
}
|
||||||
let mut label = vec![];
|
let mut label = vec![];
|
||||||
for (item, trait_ref) in &missing_assoc_types {
|
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())
|
format!(" (from trait `{}`)", trait_ref.print_trait_sugared())
|
||||||
} else {
|
} else {
|
||||||
String::new()
|
String::new()
|
||||||
};
|
};
|
||||||
label.push(format!("`{}`{}", item.name, postfix));
|
label.push(format!("`{}`{}", name, postfix));
|
||||||
}
|
}
|
||||||
if !label.is_empty() {
|
if !label.is_empty() {
|
||||||
err.span_label(
|
err.span_label(
|
||||||
|
|
|
@ -502,7 +502,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
.associated_items(trait_def_id)
|
.associated_items(trait_def_id)
|
||||||
.in_definition_order()
|
.in_definition_order()
|
||||||
.filter(|assoc| assoc.namespace() == Namespace::ValueNS)
|
.filter(|assoc| assoc.namespace() == Namespace::ValueNS)
|
||||||
.map(|cand| cand.name)
|
.map(|cand| cand.name())
|
||||||
.collect();
|
.collect();
|
||||||
if let Some(typo) = find_best_match_for_name(&names, segment.ident.name, None) {
|
if let Some(typo) = find_best_match_for_name(&names, segment.ident.name, None) {
|
||||||
diag.span_suggestion_verbose(
|
diag.span_suggestion_verbose(
|
||||||
|
|
|
@ -119,7 +119,7 @@ pub(crate) fn enforce_impl_lifetime_params_are_constrained(
|
||||||
vec![]
|
vec![]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::AssocKind::Fn { .. } | ty::AssocKind::Const => vec![],
|
ty::AssocKind::Fn { .. } | ty::AssocKind::Const { .. } => vec![],
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
|
@ -2601,8 +2601,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let input_len = fn_sig.inputs().skip_binder().len();
|
let input_len = fn_sig.inputs().skip_binder().len();
|
||||||
let order = !item.name.as_str().starts_with("new");
|
let name = item.name();
|
||||||
Some((order, item.name, input_len))
|
let order = !name.as_str().starts_with("new");
|
||||||
|
Some((order, name, input_len))
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
items.sort_by_key(|(order, _, _)| *order);
|
items.sort_by_key(|(order, _, _)| *order);
|
||||||
|
|
|
@ -683,10 +683,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
.all(|(expected, found)| self.may_coerce(*expected, *found))
|
.all(|(expected, found)| self.may_coerce(*expected, *found))
|
||||||
&& fn_sig.inputs()[1..].len() == input_types.len()
|
&& fn_sig.inputs()[1..].len() == input_types.len()
|
||||||
{
|
{
|
||||||
|
let assoc_name = assoc.name();
|
||||||
err.span_suggestion_verbose(
|
err.span_suggestion_verbose(
|
||||||
call_name.span,
|
call_name.span,
|
||||||
format!("you might have meant to use `{}`", assoc.name),
|
format!("you might have meant to use `{}`", assoc_name),
|
||||||
assoc.name,
|
assoc_name,
|
||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
@ -706,7 +707,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
tcx.def_span(assoc.def_id),
|
tcx.def_span(assoc.def_id),
|
||||||
format!(
|
format!(
|
||||||
"there's is a method with similar name `{}`, but the arguments don't match",
|
"there's is a method with similar name `{}`, but the arguments don't match",
|
||||||
assoc.name,
|
assoc.name(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
@ -718,7 +719,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
format!(
|
format!(
|
||||||
"there's is a method with similar name `{}`, but their argument count \
|
"there's is a method with similar name `{}`, but their argument count \
|
||||||
doesn't match",
|
doesn't match",
|
||||||
assoc.name,
|
assoc.name(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -381,9 +381,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
let mut suggestions = methods
|
let mut suggestions = methods
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|conversion_method| {
|
.filter_map(|conversion_method| {
|
||||||
|
let conversion_method_name = conversion_method.name();
|
||||||
let receiver_method_ident = expr.method_ident();
|
let receiver_method_ident = expr.method_ident();
|
||||||
if let Some(method_ident) = receiver_method_ident
|
if let Some(method_ident) = receiver_method_ident
|
||||||
&& method_ident.name == conversion_method.name
|
&& method_ident.name == conversion_method_name
|
||||||
{
|
{
|
||||||
return None; // do not suggest code that is already there (#53348)
|
return None; // do not suggest code that is already there (#53348)
|
||||||
}
|
}
|
||||||
|
@ -391,20 +392,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
let method_call_list = [sym::to_vec, sym::to_string];
|
let method_call_list = [sym::to_vec, sym::to_string];
|
||||||
let mut sugg = if let ExprKind::MethodCall(receiver_method, ..) = expr.kind
|
let mut sugg = if let ExprKind::MethodCall(receiver_method, ..) = expr.kind
|
||||||
&& receiver_method.ident.name == sym::clone
|
&& receiver_method.ident.name == sym::clone
|
||||||
&& method_call_list.contains(&conversion_method.name)
|
&& method_call_list.contains(&conversion_method_name)
|
||||||
// If receiver is `.clone()` and found type has one of those methods,
|
// If receiver is `.clone()` and found type has one of those methods,
|
||||||
// we guess that the user wants to convert from a slice type (`&[]` or `&str`)
|
// we guess that the user wants to convert from a slice type (`&[]` or `&str`)
|
||||||
// to an owned type (`Vec` or `String`). These conversions clone internally,
|
// to an owned type (`Vec` or `String`). These conversions clone internally,
|
||||||
// so we remove the user's `clone` call.
|
// so we remove the user's `clone` call.
|
||||||
{
|
{
|
||||||
vec![(receiver_method.ident.span, conversion_method.name.to_string())]
|
vec![(receiver_method.ident.span, conversion_method_name.to_string())]
|
||||||
} else if expr.precedence() < ExprPrecedence::Unambiguous {
|
} else if expr.precedence() < ExprPrecedence::Unambiguous {
|
||||||
vec![
|
vec![
|
||||||
(expr.span.shrink_to_lo(), "(".to_string()),
|
(expr.span.shrink_to_lo(), "(".to_string()),
|
||||||
(expr.span.shrink_to_hi(), format!(").{}()", conversion_method.name)),
|
(expr.span.shrink_to_hi(), format!(").{}()", conversion_method_name)),
|
||||||
]
|
]
|
||||||
} else {
|
} else {
|
||||||
vec![(expr.span.shrink_to_hi(), format!(".{}()", conversion_method.name))]
|
vec![(expr.span.shrink_to_hi(), format!(".{}()", conversion_method_name))]
|
||||||
};
|
};
|
||||||
let struct_pat_shorthand_field =
|
let struct_pat_shorthand_field =
|
||||||
self.tcx.hir_maybe_get_struct_pattern_shorthand_field(expr);
|
self.tcx.hir_maybe_get_struct_pattern_shorthand_field(expr);
|
||||||
|
|
|
@ -266,7 +266,7 @@ fn infer_type_if_missing<'tcx>(fcx: &FnCtxt<'_, 'tcx>, node: Node<'tcx>) -> Opti
|
||||||
let expected_type = if let Some(&hir::Ty { kind: hir::TyKind::Infer(()), span, .. }) = node.ty()
|
let expected_type = if let Some(&hir::Ty { kind: hir::TyKind::Infer(()), span, .. }) = node.ty()
|
||||||
{
|
{
|
||||||
if let Some(item) = tcx.opt_associated_item(def_id.into())
|
if let Some(item) = tcx.opt_associated_item(def_id.into())
|
||||||
&& let ty::AssocKind::Const = item.kind
|
&& let ty::AssocKind::Const { .. } = item.kind
|
||||||
&& let ty::AssocItemContainer::Impl = item.container
|
&& let ty::AssocItemContainer::Impl = item.container
|
||||||
&& let Some(trait_item_def_id) = item.trait_item_def_id
|
&& let Some(trait_item_def_id) = item.trait_item_def_id
|
||||||
{
|
{
|
||||||
|
|
|
@ -1671,7 +1671,7 @@ impl<'tcx> Pick<'tcx> {
|
||||||
/// Do not use for type checking.
|
/// Do not use for type checking.
|
||||||
pub(crate) fn differs_from(&self, other: &Self) -> bool {
|
pub(crate) fn differs_from(&self, other: &Self) -> bool {
|
||||||
let Self {
|
let Self {
|
||||||
item: AssocItem { def_id, name: _, kind: _, container: _, trait_item_def_id: _ },
|
item: AssocItem { def_id, kind: _, container: _, trait_item_def_id: _ },
|
||||||
kind: _,
|
kind: _,
|
||||||
import_ids: _,
|
import_ids: _,
|
||||||
autoderefs: _,
|
autoderefs: _,
|
||||||
|
@ -1714,17 +1714,12 @@ impl<'tcx> Pick<'tcx> {
|
||||||
tcx.def_path_str(self.item.def_id),
|
tcx.def_path_str(self.item.def_id),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
(ty::AssocKind::Const, ty::AssocItemContainer::Trait) => {
|
(ty::AssocKind::Const { name }, ty::AssocItemContainer::Trait) => {
|
||||||
let def_id = self.item.container_id(tcx);
|
let def_id = self.item.container_id(tcx);
|
||||||
lint.span_suggestion(
|
lint.span_suggestion(
|
||||||
span,
|
span,
|
||||||
"use the fully qualified path to the associated const",
|
"use the fully qualified path to the associated const",
|
||||||
format!(
|
format!("<{} as {}>::{}", self.self_ty, tcx.def_path_str(def_id), name),
|
||||||
"<{} as {}>::{}",
|
|
||||||
self.self_ty,
|
|
||||||
tcx.def_path_str(def_id),
|
|
||||||
self.item.name
|
|
||||||
),
|
|
||||||
Applicability::MachineApplicable,
|
Applicability::MachineApplicable,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -2213,7 +2208,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||||
let best_name = {
|
let best_name = {
|
||||||
let names = applicable_close_candidates
|
let names = applicable_close_candidates
|
||||||
.iter()
|
.iter()
|
||||||
.map(|cand| cand.name)
|
.map(|cand| cand.name())
|
||||||
.collect::<Vec<Symbol>>();
|
.collect::<Vec<Symbol>>();
|
||||||
find_best_match_for_name_with_substrings(
|
find_best_match_for_name_with_substrings(
|
||||||
&names,
|
&names,
|
||||||
|
@ -2225,10 +2220,12 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||||
applicable_close_candidates
|
applicable_close_candidates
|
||||||
.iter()
|
.iter()
|
||||||
.find(|cand| self.matches_by_doc_alias(cand.def_id))
|
.find(|cand| self.matches_by_doc_alias(cand.def_id))
|
||||||
.map(|cand| cand.name)
|
.map(|cand| cand.name())
|
||||||
});
|
});
|
||||||
Ok(best_name.and_then(|best_name| {
|
Ok(best_name.and_then(|best_name| {
|
||||||
applicable_close_candidates.into_iter().find(|method| method.name == best_name)
|
applicable_close_candidates
|
||||||
|
.into_iter()
|
||||||
|
.find(|method| method.name() == best_name)
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -2246,7 +2243,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||||
Mode::MethodCall => item.is_method(),
|
Mode::MethodCall => item.is_method(),
|
||||||
Mode::Path => match item.kind {
|
Mode::Path => match item.kind {
|
||||||
ty::AssocKind::Type { .. } => false,
|
ty::AssocKind::Type { .. } => false,
|
||||||
ty::AssocKind::Fn { .. } | ty::AssocKind::Const => true,
|
ty::AssocKind::Fn { .. } | ty::AssocKind::Const { .. } => true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
// FIXME -- check for types that deref to `Self`,
|
// FIXME -- check for types that deref to `Self`,
|
||||||
|
@ -2320,7 +2317,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||||
fn is_relevant_kind_for_mode(&self, kind: ty::AssocKind) -> bool {
|
fn is_relevant_kind_for_mode(&self, kind: ty::AssocKind) -> bool {
|
||||||
match (self.mode, kind) {
|
match (self.mode, kind) {
|
||||||
(Mode::MethodCall, ty::AssocKind::Fn { .. }) => true,
|
(Mode::MethodCall, ty::AssocKind::Fn { .. }) => true,
|
||||||
(Mode::Path, ty::AssocKind::Const | ty::AssocKind::Fn { .. }) => true,
|
(Mode::Path, ty::AssocKind::Const { .. } | ty::AssocKind::Fn { .. }) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2402,7 +2399,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
match edit_distance_with_substrings(
|
match edit_distance_with_substrings(
|
||||||
name.as_str(),
|
name.as_str(),
|
||||||
x.name.as_str(),
|
x.name().as_str(),
|
||||||
max_dist,
|
max_dist,
|
||||||
) {
|
) {
|
||||||
Some(d) => d > 0,
|
Some(d) => d > 0,
|
||||||
|
|
|
@ -1722,7 +1722,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
// that had unsatisfied trait bounds
|
// that had unsatisfied trait bounds
|
||||||
if unsatisfied_predicates.is_empty()
|
if unsatisfied_predicates.is_empty()
|
||||||
// ...or if we already suggested that name because of `rustc_confusable` annotation.
|
// ...or if we already suggested that name because of `rustc_confusable` annotation.
|
||||||
&& Some(similar_candidate.name) != confusable_suggested
|
&& Some(similar_candidate.name()) != confusable_suggested
|
||||||
{
|
{
|
||||||
self.find_likely_intended_associated_item(
|
self.find_likely_intended_associated_item(
|
||||||
&mut err,
|
&mut err,
|
||||||
|
@ -1821,10 +1821,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
let def_kind = similar_candidate.as_def_kind();
|
let def_kind = similar_candidate.as_def_kind();
|
||||||
let an = self.tcx.def_kind_descr_article(def_kind, similar_candidate.def_id);
|
let an = self.tcx.def_kind_descr_article(def_kind, similar_candidate.def_id);
|
||||||
|
let similar_candidate_name = similar_candidate.name();
|
||||||
let msg = format!(
|
let msg = format!(
|
||||||
"there is {an} {} `{}` with a similar name",
|
"there is {an} {} `{}` with a similar name",
|
||||||
self.tcx.def_kind_descr(def_kind, similar_candidate.def_id),
|
self.tcx.def_kind_descr(def_kind, similar_candidate.def_id),
|
||||||
similar_candidate.name,
|
similar_candidate_name,
|
||||||
);
|
);
|
||||||
// Methods are defined within the context of a struct and their first parameter
|
// Methods are defined within the context of a struct and their first parameter
|
||||||
// is always `self`, which represents the instance of the struct the method is
|
// is always `self`, which represents the instance of the struct the method is
|
||||||
|
@ -1843,7 +1844,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
err.span_suggestion_verbose(
|
err.span_suggestion_verbose(
|
||||||
span,
|
span,
|
||||||
msg,
|
msg,
|
||||||
similar_candidate.name,
|
similar_candidate_name,
|
||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1865,7 +1866,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
err.span_suggestion_verbose(
|
err.span_suggestion_verbose(
|
||||||
span,
|
span,
|
||||||
msg,
|
msg,
|
||||||
similar_candidate.name,
|
similar_candidate_name,
|
||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1878,7 +1879,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
err.span_suggestion_verbose(
|
err.span_suggestion_verbose(
|
||||||
span,
|
span,
|
||||||
msg,
|
msg,
|
||||||
similar_candidate.name,
|
similar_candidate_name,
|
||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1918,6 +1919,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
infer::FnCall,
|
infer::FnCall,
|
||||||
fn_sig,
|
fn_sig,
|
||||||
);
|
);
|
||||||
|
let name = inherent_method.name();
|
||||||
if let Some(ref args) = call_args
|
if let Some(ref args) = call_args
|
||||||
&& fn_sig.inputs()[1..]
|
&& fn_sig.inputs()[1..]
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -1927,20 +1929,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
{
|
{
|
||||||
err.span_suggestion_verbose(
|
err.span_suggestion_verbose(
|
||||||
item_name.span,
|
item_name.span,
|
||||||
format!("you might have meant to use `{}`", inherent_method.name),
|
format!("you might have meant to use `{}`", name),
|
||||||
inherent_method.name,
|
name,
|
||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
);
|
);
|
||||||
return Some(inherent_method.name);
|
return Some(name);
|
||||||
} else if let None = call_args {
|
} else if let None = call_args {
|
||||||
err.span_note(
|
err.span_note(
|
||||||
self.tcx.def_span(inherent_method.def_id),
|
self.tcx.def_span(inherent_method.def_id),
|
||||||
format!(
|
format!("you might have meant to use method `{}`", name),
|
||||||
"you might have meant to use method `{}`",
|
|
||||||
inherent_method.name,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
return Some(inherent_method.name);
|
return Some(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2116,7 +2115,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
// Only assoc fn with no receivers and only if
|
// Only assoc fn with no receivers and only if
|
||||||
// they are resolvable
|
// they are resolvable
|
||||||
.filter(|item| {
|
.filter(|item| {
|
||||||
matches!(item.kind, ty::AssocKind::Fn { has_self: false })
|
matches!(item.kind, ty::AssocKind::Fn { has_self: false, .. })
|
||||||
&& self
|
&& self
|
||||||
.probe_for_name(
|
.probe_for_name(
|
||||||
Mode::Path,
|
Mode::Path,
|
||||||
|
|
|
@ -372,7 +372,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
.associated_item_def_ids(def_id)
|
.associated_item_def_ids(def_id)
|
||||||
.iter()
|
.iter()
|
||||||
.find(|item_def_id| {
|
.find(|item_def_id| {
|
||||||
self.tcx.associated_item(*item_def_id).name == sym::Output
|
self.tcx.associated_item(*item_def_id).name() == sym::Output
|
||||||
})
|
})
|
||||||
.cloned()
|
.cloned()
|
||||||
});
|
});
|
||||||
|
|
|
@ -1332,30 +1332,26 @@ impl<'a> CrateMetadataRef<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_associated_item(self, id: DefIndex, sess: &'a Session) -> ty::AssocItem {
|
fn get_associated_item(self, id: DefIndex, sess: &'a Session) -> ty::AssocItem {
|
||||||
let name = if self.root.tables.opt_rpitit_info.get(self, id).is_some() {
|
|
||||||
kw::Empty
|
|
||||||
} else {
|
|
||||||
self.item_name(id)
|
|
||||||
};
|
|
||||||
let kind = match self.def_kind(id) {
|
let kind = match self.def_kind(id) {
|
||||||
DefKind::AssocConst => ty::AssocKind::Const,
|
DefKind::AssocConst => ty::AssocKind::Const { name: self.item_name(id) },
|
||||||
DefKind::AssocFn => {
|
DefKind::AssocFn => ty::AssocKind::Fn {
|
||||||
ty::AssocKind::Fn { has_self: self.get_fn_has_self_parameter(id, sess) }
|
name: self.item_name(id),
|
||||||
}
|
has_self: self.get_fn_has_self_parameter(id, sess),
|
||||||
DefKind::AssocTy => ty::AssocKind::Type {
|
|
||||||
opt_rpitit_info: self
|
|
||||||
.root
|
|
||||||
.tables
|
|
||||||
.opt_rpitit_info
|
|
||||||
.get(self, id)
|
|
||||||
.map(|d| d.decode(self)),
|
|
||||||
},
|
},
|
||||||
|
DefKind::AssocTy => {
|
||||||
|
let data = if let Some(rpitit_info) = self.root.tables.opt_rpitit_info.get(self, id)
|
||||||
|
{
|
||||||
|
ty::AssocTypeData::Rpitit(rpitit_info.decode(self))
|
||||||
|
} else {
|
||||||
|
ty::AssocTypeData::Normal(self.item_name(id))
|
||||||
|
};
|
||||||
|
ty::AssocKind::Type { data }
|
||||||
|
}
|
||||||
_ => bug!("cannot get associated-item of `{:?}`", self.def_key(id)),
|
_ => bug!("cannot get associated-item of `{:?}`", self.def_key(id)),
|
||||||
};
|
};
|
||||||
let container = self.root.tables.assoc_container.get(self, id).unwrap();
|
let container = self.root.tables.assoc_container.get(self, id).unwrap();
|
||||||
|
|
||||||
ty::AssocItem {
|
ty::AssocItem {
|
||||||
name,
|
|
||||||
kind,
|
kind,
|
||||||
def_id: self.local_def_id(id),
|
def_id: self.local_def_id(id),
|
||||||
trait_item_def_id: self.get_trait_item_def_id(id),
|
trait_item_def_id: self.get_trait_item_def_id(id),
|
||||||
|
|
|
@ -1706,7 +1706,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let ty::AssocKind::Type { opt_rpitit_info: Some(rpitit_info) } = item.kind {
|
if let ty::AssocKind::Type { data: ty::AssocTypeData::Rpitit(rpitit_info) } = item.kind {
|
||||||
record!(self.tables.opt_rpitit_info[def_id] <- rpitit_info);
|
record!(self.tables.opt_rpitit_info[def_id] <- rpitit_info);
|
||||||
if matches!(rpitit_info, ty::ImplTraitInTraitData::Trait { .. }) {
|
if matches!(rpitit_info, ty::ImplTraitInTraitData::Trait { .. }) {
|
||||||
record_array!(
|
record_array!(
|
||||||
|
|
|
@ -18,7 +18,6 @@ pub enum AssocItemContainer {
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, HashStable, Eq, Hash, Encodable, Decodable)]
|
#[derive(Copy, Clone, Debug, PartialEq, HashStable, Eq, Hash, Encodable, Decodable)]
|
||||||
pub struct AssocItem {
|
pub struct AssocItem {
|
||||||
pub def_id: DefId,
|
pub def_id: DefId,
|
||||||
pub name: Symbol,
|
|
||||||
pub kind: AssocKind,
|
pub kind: AssocKind,
|
||||||
pub container: AssocItemContainer,
|
pub container: AssocItemContainer,
|
||||||
|
|
||||||
|
@ -28,8 +27,24 @@ pub struct AssocItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AssocItem {
|
impl AssocItem {
|
||||||
|
// Gets the identifier, if it has one.
|
||||||
|
pub fn opt_name(&self) -> Option<Symbol> {
|
||||||
|
match self.kind {
|
||||||
|
ty::AssocKind::Type { data: AssocTypeData::Normal(name) } => Some(name),
|
||||||
|
ty::AssocKind::Type { data: AssocTypeData::Rpitit(_) } => None,
|
||||||
|
ty::AssocKind::Const { name } => Some(name),
|
||||||
|
ty::AssocKind::Fn { name, .. } => Some(name),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gets the identifier name. Aborts if it lacks one, i.e. is an RPITIT
|
||||||
|
// associated type.
|
||||||
|
pub fn name(&self) -> Symbol {
|
||||||
|
self.opt_name().expect("name of non-Rpitit assoc item")
|
||||||
|
}
|
||||||
|
|
||||||
pub fn ident(&self, tcx: TyCtxt<'_>) -> Ident {
|
pub fn ident(&self, tcx: TyCtxt<'_>) -> Ident {
|
||||||
Ident::new(self.name, tcx.def_ident_span(self.def_id).unwrap())
|
Ident::new(self.name(), tcx.def_ident_span(self.def_id).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the defaultness of the associated item.
|
/// Gets the defaultness of the associated item.
|
||||||
|
@ -76,22 +91,18 @@ impl AssocItem {
|
||||||
// regions just fine, showing `fn(&MyType)`.
|
// regions just fine, showing `fn(&MyType)`.
|
||||||
tcx.fn_sig(self.def_id).instantiate_identity().skip_binder().to_string()
|
tcx.fn_sig(self.def_id).instantiate_identity().skip_binder().to_string()
|
||||||
}
|
}
|
||||||
ty::AssocKind::Type { .. } => format!("type {};", self.name),
|
ty::AssocKind::Type { .. } => format!("type {};", self.name()),
|
||||||
ty::AssocKind::Const => {
|
ty::AssocKind::Const { name } => {
|
||||||
format!(
|
format!("const {}: {:?};", name, tcx.type_of(self.def_id).instantiate_identity())
|
||||||
"const {}: {:?};",
|
|
||||||
self.name,
|
|
||||||
tcx.type_of(self.def_id).instantiate_identity()
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn descr(&self) -> &'static str {
|
pub fn descr(&self) -> &'static str {
|
||||||
match self.kind {
|
match self.kind {
|
||||||
ty::AssocKind::Const => "associated const",
|
ty::AssocKind::Const { .. } => "associated const",
|
||||||
ty::AssocKind::Fn { has_self: true } => "method",
|
ty::AssocKind::Fn { has_self: true, .. } => "method",
|
||||||
ty::AssocKind::Fn { has_self: false } => "associated function",
|
ty::AssocKind::Fn { has_self: false, .. } => "associated function",
|
||||||
ty::AssocKind::Type { .. } => "associated type",
|
ty::AssocKind::Type { .. } => "associated type",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,13 +110,13 @@ impl AssocItem {
|
||||||
pub fn namespace(&self) -> Namespace {
|
pub fn namespace(&self) -> Namespace {
|
||||||
match self.kind {
|
match self.kind {
|
||||||
ty::AssocKind::Type { .. } => Namespace::TypeNS,
|
ty::AssocKind::Type { .. } => Namespace::TypeNS,
|
||||||
ty::AssocKind::Const | ty::AssocKind::Fn { .. } => Namespace::ValueNS,
|
ty::AssocKind::Const { .. } | ty::AssocKind::Fn { .. } => Namespace::ValueNS,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_def_kind(&self) -> DefKind {
|
pub fn as_def_kind(&self) -> DefKind {
|
||||||
match self.kind {
|
match self.kind {
|
||||||
AssocKind::Const => DefKind::AssocConst,
|
AssocKind::Const { .. } => DefKind::AssocConst,
|
||||||
AssocKind::Fn { .. } => DefKind::AssocFn,
|
AssocKind::Fn { .. } => DefKind::AssocFn,
|
||||||
AssocKind::Type { .. } => DefKind::AssocTy,
|
AssocKind::Type { .. } => DefKind::AssocTy,
|
||||||
}
|
}
|
||||||
|
@ -119,19 +130,19 @@ impl AssocItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_method(&self) -> bool {
|
pub fn is_method(&self) -> bool {
|
||||||
matches!(self.kind, ty::AssocKind::Fn { has_self: true })
|
matches!(self.kind, ty::AssocKind::Fn { has_self: true, .. })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_tag(&self) -> AssocTag {
|
pub fn as_tag(&self) -> AssocTag {
|
||||||
match self.kind {
|
match self.kind {
|
||||||
AssocKind::Const => AssocTag::Const,
|
AssocKind::Const { .. } => AssocTag::Const,
|
||||||
AssocKind::Fn { .. } => AssocTag::Fn,
|
AssocKind::Fn { .. } => AssocTag::Fn,
|
||||||
AssocKind::Type { .. } => AssocTag::Type,
|
AssocKind::Type { .. } => AssocTag::Type,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_impl_trait_in_trait(&self) -> bool {
|
pub fn is_impl_trait_in_trait(&self) -> bool {
|
||||||
matches!(self.kind, AssocKind::Type { opt_rpitit_info: Some(_) })
|
matches!(self.kind, AssocKind::Type { data: AssocTypeData::Rpitit(_) })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if:
|
/// Returns true if:
|
||||||
|
@ -139,7 +150,7 @@ impl AssocItem {
|
||||||
/// - If it is in a trait impl, the item from the original trait has this attribute, or
|
/// - If it is in a trait impl, the item from the original trait has this attribute, or
|
||||||
/// - It is an inherent assoc const.
|
/// - It is an inherent assoc const.
|
||||||
pub fn is_type_const_capable(&self, tcx: TyCtxt<'_>) -> bool {
|
pub fn is_type_const_capable(&self, tcx: TyCtxt<'_>) -> bool {
|
||||||
if self.kind != ty::AssocKind::Const {
|
if !matches!(self.kind, ty::AssocKind::Const { .. }) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,26 +164,45 @@ impl AssocItem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, PartialEq, Debug, HashStable, Eq, Hash, Encodable, Decodable)]
|
||||||
|
pub enum AssocTypeData {
|
||||||
|
Normal(Symbol),
|
||||||
|
/// The associated type comes from an RPITIT. It has no name, and the
|
||||||
|
/// `ImplTraitInTraitData` provides additional information about its
|
||||||
|
/// source.
|
||||||
|
Rpitit(ty::ImplTraitInTraitData),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Debug, HashStable, Eq, Hash, Encodable, Decodable)]
|
#[derive(Copy, Clone, PartialEq, Debug, HashStable, Eq, Hash, Encodable, Decodable)]
|
||||||
pub enum AssocKind {
|
pub enum AssocKind {
|
||||||
Const,
|
Const { name: Symbol },
|
||||||
Fn {
|
Fn { name: Symbol, has_self: bool },
|
||||||
has_self: bool,
|
Type { data: AssocTypeData },
|
||||||
},
|
}
|
||||||
Type {
|
|
||||||
/// `Some` if the associated type comes from an RPITIT. The
|
impl AssocKind {
|
||||||
/// `ImplTraitInTraitData` provides additional information about its
|
pub fn namespace(&self) -> Namespace {
|
||||||
/// source.
|
match *self {
|
||||||
opt_rpitit_info: Option<ty::ImplTraitInTraitData>,
|
ty::AssocKind::Type { .. } => Namespace::TypeNS,
|
||||||
},
|
ty::AssocKind::Const { .. } | ty::AssocKind::Fn { .. } => Namespace::ValueNS,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_def_kind(&self) -> DefKind {
|
||||||
|
match self {
|
||||||
|
AssocKind::Const { .. } => DefKind::AssocConst,
|
||||||
|
AssocKind::Fn { .. } => DefKind::AssocFn,
|
||||||
|
AssocKind::Type { .. } => DefKind::AssocTy,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for AssocKind {
|
impl std::fmt::Display for AssocKind {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
AssocKind::Fn { has_self: true } => write!(f, "method"),
|
AssocKind::Fn { has_self: true, .. } => write!(f, "method"),
|
||||||
AssocKind::Fn { has_self: false } => write!(f, "associated function"),
|
AssocKind::Fn { has_self: false, .. } => write!(f, "associated function"),
|
||||||
AssocKind::Const => write!(f, "associated const"),
|
AssocKind::Const { .. } => write!(f, "associated const"),
|
||||||
AssocKind::Type { .. } => write!(f, "associated type"),
|
AssocKind::Type { .. } => write!(f, "associated type"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -193,17 +223,17 @@ pub enum AssocTag {
|
||||||
/// done only on items with the same name.
|
/// done only on items with the same name.
|
||||||
#[derive(Debug, Clone, PartialEq, HashStable)]
|
#[derive(Debug, Clone, PartialEq, HashStable)]
|
||||||
pub struct AssocItems {
|
pub struct AssocItems {
|
||||||
items: SortedIndexMultiMap<u32, Symbol, ty::AssocItem>,
|
items: SortedIndexMultiMap<u32, Option<Symbol>, ty::AssocItem>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AssocItems {
|
impl AssocItems {
|
||||||
/// Constructs an `AssociatedItems` map from a series of `ty::AssocItem`s in definition order.
|
/// Constructs an `AssociatedItems` map from a series of `ty::AssocItem`s in definition order.
|
||||||
pub fn new(items_in_def_order: impl IntoIterator<Item = ty::AssocItem>) -> Self {
|
pub fn new(items_in_def_order: impl IntoIterator<Item = ty::AssocItem>) -> Self {
|
||||||
let items = items_in_def_order.into_iter().map(|item| (item.name, item)).collect();
|
let items = items_in_def_order.into_iter().map(|item| (item.opt_name(), item)).collect();
|
||||||
AssocItems { items }
|
AssocItems { items }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a slice of associated items in the order they were defined.
|
/// Returns an iterator over associated items in the order they were defined.
|
||||||
///
|
///
|
||||||
/// New code should avoid relying on definition order. If you need a particular associated item
|
/// New code should avoid relying on definition order. If you need a particular associated item
|
||||||
/// for a known trait, make that trait a lang item instead of indexing this array.
|
/// for a known trait, make that trait a lang item instead of indexing this array.
|
||||||
|
@ -220,7 +250,8 @@ impl AssocItems {
|
||||||
&self,
|
&self,
|
||||||
name: Symbol,
|
name: Symbol,
|
||||||
) -> impl '_ + Iterator<Item = &ty::AssocItem> {
|
) -> impl '_ + Iterator<Item = &ty::AssocItem> {
|
||||||
self.items.get_by_key(name)
|
assert!(!name.is_empty());
|
||||||
|
self.items.get_by_key(Some(name))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the associated item with the given identifier and `AssocKind`, if one exists.
|
/// Returns the associated item with the given identifier and `AssocKind`, if one exists.
|
||||||
|
|
|
@ -1611,9 +1611,10 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
/// about where that RPITIT came from.
|
/// about where that RPITIT came from.
|
||||||
pub fn opt_rpitit_info(self, def_id: DefId) -> Option<ImplTraitInTraitData> {
|
pub fn opt_rpitit_info(self, def_id: DefId) -> Option<ImplTraitInTraitData> {
|
||||||
if let DefKind::AssocTy = self.def_kind(def_id)
|
if let DefKind::AssocTy = self.def_kind(def_id)
|
||||||
&& let AssocKind::Type { opt_rpitit_info } = self.associated_item(def_id).kind
|
&& let AssocKind::Type { data: AssocTypeData::Rpitit(rpitit_info) } =
|
||||||
|
self.associated_item(def_id).kind
|
||||||
{
|
{
|
||||||
opt_rpitit_info
|
Some(rpitit_info)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
|
@ -1214,7 +1214,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
||||||
&& assoc
|
&& assoc
|
||||||
.trait_container(tcx)
|
.trait_container(tcx)
|
||||||
.is_some_and(|def_id| tcx.is_lang_item(def_id, LangItem::Coroutine))
|
.is_some_and(|def_id| tcx.is_lang_item(def_id, LangItem::Coroutine))
|
||||||
&& assoc.name == rustc_span::sym::Return
|
&& assoc.opt_name() == Some(rustc_span::sym::Return)
|
||||||
{
|
{
|
||||||
if let ty::Coroutine(_, args) = args.type_at(0).kind() {
|
if let ty::Coroutine(_, args) = args.type_at(0).kind() {
|
||||||
let return_ty = args.as_coroutine().return_ty();
|
let return_ty = args.as_coroutine().return_ty();
|
||||||
|
@ -1237,7 +1237,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
||||||
p!(", ");
|
p!(", ");
|
||||||
}
|
}
|
||||||
|
|
||||||
p!(write("{} = ", tcx.associated_item(assoc_item_def_id).name));
|
p!(write("{} = ", tcx.associated_item(assoc_item_def_id).name()));
|
||||||
|
|
||||||
match term.unpack() {
|
match term.unpack() {
|
||||||
TermKind::Ty(ty) => p!(print(ty)),
|
TermKind::Ty(ty) => p!(print(ty)),
|
||||||
|
@ -3291,7 +3291,7 @@ define_print! {
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::ExistentialProjection<'tcx> {
|
ty::ExistentialProjection<'tcx> {
|
||||||
let name = cx.tcx().associated_item(self.def_id).name;
|
let name = cx.tcx().associated_item(self.def_id).name();
|
||||||
// The args don't contain the self ty (as it has been erased) but the corresp.
|
// The args don't contain the self ty (as it has been erased) but the corresp.
|
||||||
// generics do as the trait always has a self ty param. We need to offset.
|
// generics do as the trait always has a self ty param. We need to offset.
|
||||||
let args = &self.args[cx.tcx().generics_of(self.def_id).parent_count - 1..];
|
let args = &self.args[cx.tcx().generics_of(self.def_id).parent_count - 1..];
|
||||||
|
|
|
@ -42,7 +42,7 @@ impl<'a, 'tcx> UndefinedTransmutesChecker<'a, 'tcx> {
|
||||||
if self.tcx.is_const_fn(def_id)
|
if self.tcx.is_const_fn(def_id)
|
||||||
|| matches!(
|
|| matches!(
|
||||||
self.tcx.opt_associated_item(def_id),
|
self.tcx.opt_associated_item(def_id),
|
||||||
Some(AssocItem { kind: AssocKind::Const, .. })
|
Some(AssocItem { kind: AssocKind::Const { .. }, .. })
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
let fn_sig = function.ty(self.body, self.tcx).fn_sig(self.tcx).skip_binder();
|
let fn_sig = function.ty(self.body, self.tcx).fn_sig(self.tcx).skip_binder();
|
||||||
|
|
|
@ -2007,8 +2007,9 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
|
||||||
if def.did() != def_id {
|
if def.did() != def_id {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let order = !item.name.as_str().starts_with("new");
|
let name = item.name();
|
||||||
Some((order, item.name, input_len))
|
let order = !name.as_str().starts_with("new");
|
||||||
|
Some((order, name, input_len))
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
items.sort_by_key(|(order, _, _)| *order);
|
items.sort_by_key(|(order, _, _)| *order);
|
||||||
|
|
|
@ -895,12 +895,19 @@ impl<'tcx> Stable<'tcx> for ty::AssocKind {
|
||||||
type T = stable_mir::ty::AssocKind;
|
type T = stable_mir::ty::AssocKind;
|
||||||
|
|
||||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||||
use stable_mir::ty::AssocKind;
|
use stable_mir::ty::{AssocKind, AssocTypeData};
|
||||||
match *self {
|
match *self {
|
||||||
ty::AssocKind::Const => AssocKind::Const,
|
ty::AssocKind::Const { name } => AssocKind::Const { name: name.to_string() },
|
||||||
ty::AssocKind::Fn { has_self } => AssocKind::Fn { has_self },
|
ty::AssocKind::Fn { name, has_self } => {
|
||||||
ty::AssocKind::Type { opt_rpitit_info } => AssocKind::Type {
|
AssocKind::Fn { name: name.to_string(), has_self }
|
||||||
opt_rpitit_info: opt_rpitit_info.map(|rpitit| rpitit.stable(tables)),
|
}
|
||||||
|
ty::AssocKind::Type { data } => AssocKind::Type {
|
||||||
|
data: match data {
|
||||||
|
ty::AssocTypeData::Normal(name) => AssocTypeData::Normal(name.to_string()),
|
||||||
|
ty::AssocTypeData::Rpitit(rpitit) => {
|
||||||
|
AssocTypeData::Rpitit(rpitit.stable(tables))
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -924,7 +931,6 @@ impl<'tcx> Stable<'tcx> for ty::AssocItem {
|
||||||
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
|
||||||
stable_mir::ty::AssocItem {
|
stable_mir::ty::AssocItem {
|
||||||
def_id: tables.assoc_def(self.def_id),
|
def_id: tables.assoc_def(self.def_id),
|
||||||
name: self.name.to_string(),
|
|
||||||
kind: self.kind.stable(tables),
|
kind: self.kind.stable(tables),
|
||||||
container: self.container.stable(tables),
|
container: self.container.stable(tables),
|
||||||
trait_item_def_id: self.trait_item_def_id.map(|did| tables.assoc_def(did)),
|
trait_item_def_id: self.trait_item_def_id.map(|did| tables.assoc_def(did)),
|
||||||
|
|
|
@ -22,9 +22,9 @@ impl Display for Ty {
|
||||||
impl Display for AssocKind {
|
impl Display for AssocKind {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
AssocKind::Fn { has_self: true } => write!(f, "method"),
|
AssocKind::Fn { has_self: true, .. } => write!(f, "method"),
|
||||||
AssocKind::Fn { has_self: false } => write!(f, "associated function"),
|
AssocKind::Fn { has_self: false, .. } => write!(f, "associated function"),
|
||||||
AssocKind::Const => write!(f, "associated const"),
|
AssocKind::Const { .. } => write!(f, "associated const"),
|
||||||
AssocKind::Type { .. } => write!(f, "associated type"),
|
AssocKind::Type { .. } => write!(f, "associated type"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1578,7 +1578,6 @@ crate_def! {
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||||
pub struct AssocItem {
|
pub struct AssocItem {
|
||||||
pub def_id: AssocDef,
|
pub def_id: AssocDef,
|
||||||
pub name: Symbol,
|
|
||||||
pub kind: AssocKind,
|
pub kind: AssocKind,
|
||||||
pub container: AssocItemContainer,
|
pub container: AssocItemContainer,
|
||||||
|
|
||||||
|
@ -1587,18 +1586,20 @@ pub struct AssocItem {
|
||||||
pub trait_item_def_id: Option<AssocDef>,
|
pub trait_item_def_id: Option<AssocDef>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq, Debug, Eq, Serialize)]
|
||||||
|
pub enum AssocTypeData {
|
||||||
|
Normal(Symbol),
|
||||||
|
/// The associated type comes from an RPITIT. It has no name, and the
|
||||||
|
/// `ImplTraitInTraitData` provides additional information about its
|
||||||
|
/// source.
|
||||||
|
Rpitit(ImplTraitInTraitData),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||||
pub enum AssocKind {
|
pub enum AssocKind {
|
||||||
Const,
|
Const { name: Symbol },
|
||||||
Fn {
|
Fn { name: Symbol, has_self: bool },
|
||||||
has_self: bool,
|
Type { data: AssocTypeData },
|
||||||
},
|
|
||||||
Type {
|
|
||||||
/// `Some` if the associated type comes from an RPITIT. The
|
|
||||||
/// `ImplTraitInTraitData` provides additional information about its
|
|
||||||
/// source.
|
|
||||||
opt_rpitit_info: Option<ImplTraitInTraitData>,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||||
|
@ -1615,6 +1616,6 @@ pub enum ImplTraitInTraitData {
|
||||||
|
|
||||||
impl AssocItem {
|
impl AssocItem {
|
||||||
pub fn is_impl_trait_in_trait(&self) -> bool {
|
pub fn is_impl_trait_in_trait(&self) -> bool {
|
||||||
matches!(self.kind, AssocKind::Type { opt_rpitit_info: Some(_) })
|
matches!(self.kind, AssocKind::Type { data: AssocTypeData::Rpitit(_) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -615,7 +615,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
|
||||||
cx.print_def_path(trait_ref.def_id, trait_ref.args)?;
|
cx.print_def_path(trait_ref.def_id, trait_ref.args)?;
|
||||||
}
|
}
|
||||||
ty::ExistentialPredicate::Projection(projection) => {
|
ty::ExistentialPredicate::Projection(projection) => {
|
||||||
let name = cx.tcx.associated_item(projection.def_id).name;
|
let name = cx.tcx.associated_item(projection.def_id).name();
|
||||||
cx.push("p");
|
cx.push("p");
|
||||||
cx.push_ident(name.as_str());
|
cx.push_ident(name.as_str());
|
||||||
match projection.term.unpack() {
|
match projection.term.unpack() {
|
||||||
|
|
|
@ -2340,7 +2340,7 @@ impl<'tcx> ObligationCause<'tcx> {
|
||||||
ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Type { .. }, .. } => {
|
ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Type { .. }, .. } => {
|
||||||
ObligationCauseFailureCode::TypeCompat { span, subdiags }
|
ObligationCauseFailureCode::TypeCompat { span, subdiags }
|
||||||
}
|
}
|
||||||
ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Const, .. } => {
|
ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Const { .. }, .. } => {
|
||||||
ObligationCauseFailureCode::ConstCompat { span, subdiags }
|
ObligationCauseFailureCode::ConstCompat { span, subdiags }
|
||||||
}
|
}
|
||||||
ObligationCauseCode::BlockTailExpression(.., hir::MatchSource::TryDesugar(_)) => {
|
ObligationCauseCode::BlockTailExpression(.., hir::MatchSource::TryDesugar(_)) => {
|
||||||
|
@ -2404,7 +2404,7 @@ impl<'tcx> ObligationCause<'tcx> {
|
||||||
ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Type { .. }, .. } => {
|
ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Type { .. }, .. } => {
|
||||||
"associated type is compatible with trait"
|
"associated type is compatible with trait"
|
||||||
}
|
}
|
||||||
ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Const, .. } => {
|
ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Const { .. }, .. } => {
|
||||||
"const is compatible with trait"
|
"const is compatible with trait"
|
||||||
}
|
}
|
||||||
ObligationCauseCode::MainFunctionType => "`main` function has the correct type",
|
ObligationCauseCode::MainFunctionType => "`main` function has the correct type",
|
||||||
|
@ -2428,7 +2428,7 @@ impl IntoDiagArg for ObligationCauseAsDiagArg<'_> {
|
||||||
ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Type { .. }, .. } => {
|
ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Type { .. }, .. } => {
|
||||||
"type_compat"
|
"type_compat"
|
||||||
}
|
}
|
||||||
ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Const, .. } => {
|
ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Const { .. }, .. } => {
|
||||||
"const_compat"
|
"const_compat"
|
||||||
}
|
}
|
||||||
ObligationCauseCode::MainFunctionType => "fn_main_correct_type",
|
ObligationCauseCode::MainFunctionType => "fn_main_correct_type",
|
||||||
|
|
|
@ -783,7 +783,7 @@ fn foo(&self) -> Self::T { String::new() }
|
||||||
.in_definition_order()
|
.in_definition_order()
|
||||||
.filter(|item| {
|
.filter(|item| {
|
||||||
item.is_fn()
|
item.is_fn()
|
||||||
&& Some(item.name) != current_method_ident
|
&& Some(item.name()) != current_method_ident
|
||||||
&& !tcx.is_doc_hidden(item.def_id)
|
&& !tcx.is_doc_hidden(item.def_id)
|
||||||
})
|
})
|
||||||
.filter_map(|item| {
|
.filter_map(|item| {
|
||||||
|
|
|
@ -1017,7 +1017,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||||
infer::BoundRegion(_, br, infer::AssocTypeProjection(def_id)) => format!(
|
infer::BoundRegion(_, br, infer::AssocTypeProjection(def_id)) => format!(
|
||||||
" for lifetime parameter {}in trait containing associated type `{}`",
|
" for lifetime parameter {}in trait containing associated type `{}`",
|
||||||
br_string(br),
|
br_string(br),
|
||||||
self.tcx.associated_item(def_id).name
|
self.tcx.associated_item(def_id).name()
|
||||||
),
|
),
|
||||||
infer::RegionParameterDefinition(_, name) => {
|
infer::RegionParameterDefinition(_, name) => {
|
||||||
format!(" for lifetime parameter `{name}`")
|
format!(" for lifetime parameter `{name}`")
|
||||||
|
|
|
@ -348,7 +348,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||||
&& let None = self.tainted_by_errors()
|
&& let None = self.tainted_by_errors()
|
||||||
{
|
{
|
||||||
let (verb, noun) = match self.tcx.associated_item(item_id).kind {
|
let (verb, noun) = match self.tcx.associated_item(item_id).kind {
|
||||||
ty::AssocKind::Const => ("refer to the", "constant"),
|
ty::AssocKind::Const { .. } => ("refer to the", "constant"),
|
||||||
ty::AssocKind::Fn { .. } => ("call", "function"),
|
ty::AssocKind::Fn { .. } => ("call", "function"),
|
||||||
// This is already covered by E0223, but this following single match
|
// This is already covered by E0223, but this following single match
|
||||||
// arm doesn't hurt here.
|
// arm doesn't hurt here.
|
||||||
|
|
|
@ -2112,7 +2112,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||||
trait_ref: DefId,
|
trait_ref: DefId,
|
||||||
) {
|
) {
|
||||||
if let Some(assoc_item) = self.tcx.opt_associated_item(item_def_id) {
|
if let Some(assoc_item) = self.tcx.opt_associated_item(item_def_id) {
|
||||||
if let ty::AssocKind::Const | ty::AssocKind::Type { .. } = assoc_item.kind {
|
if let ty::AssocKind::Const { .. } | ty::AssocKind::Type { .. } = assoc_item.kind {
|
||||||
err.note(format!(
|
err.note(format!(
|
||||||
"{}s cannot be accessed directly on a `trait`, they can only be \
|
"{}s cannot be accessed directly on a `trait`, they can only be \
|
||||||
accessed through a specific `impl`",
|
accessed through a specific `impl`",
|
||||||
|
@ -2121,7 +2121,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||||
err.span_suggestion(
|
err.span_suggestion(
|
||||||
span,
|
span,
|
||||||
"use the fully qualified path to an implementation",
|
"use the fully qualified path to an implementation",
|
||||||
format!("<Type as {}>::{}", self.tcx.def_path_str(trait_ref), assoc_item.name),
|
format!(
|
||||||
|
"<Type as {}>::{}",
|
||||||
|
self.tcx.def_path_str(trait_ref),
|
||||||
|
assoc_item.name()
|
||||||
|
),
|
||||||
Applicability::HasPlaceholders,
|
Applicability::HasPlaceholders,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -298,31 +298,33 @@ pub fn dyn_compatibility_violations_for_assoc_item(
|
||||||
match item.kind {
|
match item.kind {
|
||||||
// Associated consts are never dyn-compatible, as they can't have `where` bounds yet at all,
|
// Associated consts are never dyn-compatible, as they can't have `where` bounds yet at all,
|
||||||
// and associated const bounds in trait objects aren't a thing yet either.
|
// and associated const bounds in trait objects aren't a thing yet either.
|
||||||
ty::AssocKind::Const => {
|
ty::AssocKind::Const { name } => {
|
||||||
vec![DynCompatibilityViolation::AssocConst(item.name, item.ident(tcx).span)]
|
vec![DynCompatibilityViolation::AssocConst(name, item.ident(tcx).span)]
|
||||||
}
|
}
|
||||||
ty::AssocKind::Fn { .. } => virtual_call_violations_for_method(tcx, trait_def_id, item)
|
ty::AssocKind::Fn { name, .. } => {
|
||||||
.into_iter()
|
virtual_call_violations_for_method(tcx, trait_def_id, item)
|
||||||
.map(|v| {
|
.into_iter()
|
||||||
let node = tcx.hir_get_if_local(item.def_id);
|
.map(|v| {
|
||||||
// Get an accurate span depending on the violation.
|
let node = tcx.hir_get_if_local(item.def_id);
|
||||||
let span = match (&v, node) {
|
// Get an accurate span depending on the violation.
|
||||||
(MethodViolationCode::ReferencesSelfInput(Some(span)), _) => *span,
|
let span = match (&v, node) {
|
||||||
(MethodViolationCode::UndispatchableReceiver(Some(span)), _) => *span,
|
(MethodViolationCode::ReferencesSelfInput(Some(span)), _) => *span,
|
||||||
(MethodViolationCode::ReferencesImplTraitInTrait(span), _) => *span,
|
(MethodViolationCode::UndispatchableReceiver(Some(span)), _) => *span,
|
||||||
(MethodViolationCode::ReferencesSelfOutput, Some(node)) => {
|
(MethodViolationCode::ReferencesImplTraitInTrait(span), _) => *span,
|
||||||
node.fn_decl().map_or(item.ident(tcx).span, |decl| decl.output.span())
|
(MethodViolationCode::ReferencesSelfOutput, Some(node)) => {
|
||||||
}
|
node.fn_decl().map_or(item.ident(tcx).span, |decl| decl.output.span())
|
||||||
_ => item.ident(tcx).span,
|
}
|
||||||
};
|
_ => item.ident(tcx).span,
|
||||||
|
};
|
||||||
|
|
||||||
DynCompatibilityViolation::Method(item.name, v, span)
|
DynCompatibilityViolation::Method(name, v, span)
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect()
|
||||||
|
}
|
||||||
// Associated types can only be dyn-compatible if they have `Self: Sized` bounds.
|
// Associated types can only be dyn-compatible if they have `Self: Sized` bounds.
|
||||||
ty::AssocKind::Type { .. } => {
|
ty::AssocKind::Type { .. } => {
|
||||||
if !tcx.generics_of(item.def_id).is_own_empty() && !item.is_impl_trait_in_trait() {
|
if !tcx.generics_of(item.def_id).is_own_empty() && !item.is_impl_trait_in_trait() {
|
||||||
vec![DynCompatibilityViolation::GAT(item.name, item.ident(tcx).span)]
|
vec![DynCompatibilityViolation::GAT(item.name(), item.ident(tcx).span)]
|
||||||
} else {
|
} else {
|
||||||
// We will permit associated types if they are explicitly mentioned in the trait object.
|
// We will permit associated types if they are explicitly mentioned in the trait object.
|
||||||
// We can't check this here, as here we only check if it is guaranteed to not be possible.
|
// We can't check this here, as here we only check if it is guaranteed to not be possible.
|
||||||
|
|
|
@ -1393,7 +1393,7 @@ fn confirm_future_candidate<'cx, 'tcx>(
|
||||||
coroutine_sig,
|
coroutine_sig,
|
||||||
);
|
);
|
||||||
|
|
||||||
debug_assert_eq!(tcx.associated_item(obligation.predicate.def_id).name, sym::Output);
|
debug_assert_eq!(tcx.associated_item(obligation.predicate.def_id).name(), sym::Output);
|
||||||
|
|
||||||
let predicate = ty::ProjectionPredicate {
|
let predicate = ty::ProjectionPredicate {
|
||||||
projection_term: ty::AliasTerm::new_from_args(
|
projection_term: ty::AliasTerm::new_from_args(
|
||||||
|
@ -1439,7 +1439,7 @@ fn confirm_iterator_candidate<'cx, 'tcx>(
|
||||||
gen_sig,
|
gen_sig,
|
||||||
);
|
);
|
||||||
|
|
||||||
debug_assert_eq!(tcx.associated_item(obligation.predicate.def_id).name, sym::Item);
|
debug_assert_eq!(tcx.associated_item(obligation.predicate.def_id).name(), sym::Item);
|
||||||
|
|
||||||
let predicate = ty::ProjectionPredicate {
|
let predicate = ty::ProjectionPredicate {
|
||||||
projection_term: ty::AliasTerm::new_from_args(
|
projection_term: ty::AliasTerm::new_from_args(
|
||||||
|
@ -1485,7 +1485,7 @@ fn confirm_async_iterator_candidate<'cx, 'tcx>(
|
||||||
gen_sig,
|
gen_sig,
|
||||||
);
|
);
|
||||||
|
|
||||||
debug_assert_eq!(tcx.associated_item(obligation.predicate.def_id).name, sym::Item);
|
debug_assert_eq!(tcx.associated_item(obligation.predicate.def_id).name(), sym::Item);
|
||||||
|
|
||||||
let ty::Adt(_poll_adt, args) = *yield_ty.kind() else {
|
let ty::Adt(_poll_adt, args) = *yield_ty.kind() else {
|
||||||
bug!();
|
bug!();
|
||||||
|
@ -2005,7 +2005,8 @@ fn confirm_impl_candidate<'cx, 'tcx>(
|
||||||
if !assoc_ty.item.defaultness(tcx).has_value() {
|
if !assoc_ty.item.defaultness(tcx).has_value() {
|
||||||
debug!(
|
debug!(
|
||||||
"confirm_impl_candidate: no associated type {:?} for {:?}",
|
"confirm_impl_candidate: no associated type {:?} for {:?}",
|
||||||
assoc_ty.item.name, obligation.predicate
|
assoc_ty.item.name(),
|
||||||
|
obligation.predicate
|
||||||
);
|
);
|
||||||
if tcx.impl_self_is_guaranteed_unsized(impl_def_id) {
|
if tcx.impl_self_is_guaranteed_unsized(impl_def_id) {
|
||||||
// We treat this projection as rigid here, which is represented via
|
// We treat this projection as rigid here, which is represented via
|
||||||
|
|
|
@ -6,7 +6,6 @@ use rustc_hir::{self as hir, AmbigArg};
|
||||||
use rustc_middle::query::Providers;
|
use rustc_middle::query::Providers;
|
||||||
use rustc_middle::ty::{self, ImplTraitInTraitData, TyCtxt};
|
use rustc_middle::ty::{self, ImplTraitInTraitData, TyCtxt};
|
||||||
use rustc_middle::{bug, span_bug};
|
use rustc_middle::{bug, span_bug};
|
||||||
use rustc_span::kw;
|
|
||||||
|
|
||||||
pub(crate) fn provide(providers: &mut Providers) {
|
pub(crate) fn provide(providers: &mut Providers) {
|
||||||
*providers = Providers {
|
*providers = Providers {
|
||||||
|
@ -129,14 +128,14 @@ fn associated_item(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::AssocItem {
|
||||||
|
|
||||||
fn associated_item_from_trait_item_ref(trait_item_ref: &hir::TraitItemRef) -> ty::AssocItem {
|
fn associated_item_from_trait_item_ref(trait_item_ref: &hir::TraitItemRef) -> ty::AssocItem {
|
||||||
let owner_id = trait_item_ref.id.owner_id;
|
let owner_id = trait_item_ref.id.owner_id;
|
||||||
|
let name = trait_item_ref.ident.name;
|
||||||
let kind = match trait_item_ref.kind {
|
let kind = match trait_item_ref.kind {
|
||||||
hir::AssocItemKind::Const => ty::AssocKind::Const,
|
hir::AssocItemKind::Const => ty::AssocKind::Const { name },
|
||||||
hir::AssocItemKind::Fn { has_self } => ty::AssocKind::Fn { has_self },
|
hir::AssocItemKind::Fn { has_self } => ty::AssocKind::Fn { name, has_self },
|
||||||
hir::AssocItemKind::Type => ty::AssocKind::Type { opt_rpitit_info: None },
|
hir::AssocItemKind::Type => ty::AssocKind::Type { data: ty::AssocTypeData::Normal(name) },
|
||||||
};
|
};
|
||||||
|
|
||||||
ty::AssocItem {
|
ty::AssocItem {
|
||||||
name: trait_item_ref.ident.name,
|
|
||||||
kind,
|
kind,
|
||||||
def_id: owner_id.to_def_id(),
|
def_id: owner_id.to_def_id(),
|
||||||
trait_item_def_id: Some(owner_id.to_def_id()),
|
trait_item_def_id: Some(owner_id.to_def_id()),
|
||||||
|
@ -146,14 +145,14 @@ fn associated_item_from_trait_item_ref(trait_item_ref: &hir::TraitItemRef) -> ty
|
||||||
|
|
||||||
fn associated_item_from_impl_item_ref(impl_item_ref: &hir::ImplItemRef) -> ty::AssocItem {
|
fn associated_item_from_impl_item_ref(impl_item_ref: &hir::ImplItemRef) -> ty::AssocItem {
|
||||||
let def_id = impl_item_ref.id.owner_id;
|
let def_id = impl_item_ref.id.owner_id;
|
||||||
|
let name = impl_item_ref.ident.name;
|
||||||
let kind = match impl_item_ref.kind {
|
let kind = match impl_item_ref.kind {
|
||||||
hir::AssocItemKind::Const => ty::AssocKind::Const,
|
hir::AssocItemKind::Const => ty::AssocKind::Const { name },
|
||||||
hir::AssocItemKind::Fn { has_self } => ty::AssocKind::Fn { has_self },
|
hir::AssocItemKind::Fn { has_self } => ty::AssocKind::Fn { name, has_self },
|
||||||
hir::AssocItemKind::Type => ty::AssocKind::Type { opt_rpitit_info: None },
|
hir::AssocItemKind::Type => ty::AssocKind::Type { data: ty::AssocTypeData::Normal(name) },
|
||||||
};
|
};
|
||||||
|
|
||||||
ty::AssocItem {
|
ty::AssocItem {
|
||||||
name: impl_item_ref.ident.name,
|
|
||||||
kind,
|
kind,
|
||||||
def_id: def_id.to_def_id(),
|
def_id: def_id.to_def_id(),
|
||||||
trait_item_def_id: impl_item_ref.trait_item_def_id,
|
trait_item_def_id: impl_item_ref.trait_item_def_id,
|
||||||
|
@ -260,9 +259,8 @@ fn associated_type_for_impl_trait_in_trait(
|
||||||
trait_assoc_ty.def_ident_span(Some(span));
|
trait_assoc_ty.def_ident_span(Some(span));
|
||||||
|
|
||||||
trait_assoc_ty.associated_item(ty::AssocItem {
|
trait_assoc_ty.associated_item(ty::AssocItem {
|
||||||
name: kw::Empty,
|
|
||||||
kind: ty::AssocKind::Type {
|
kind: ty::AssocKind::Type {
|
||||||
opt_rpitit_info: Some(ImplTraitInTraitData::Trait {
|
data: ty::AssocTypeData::Rpitit(ImplTraitInTraitData::Trait {
|
||||||
fn_def_id: fn_def_id.to_def_id(),
|
fn_def_id: fn_def_id.to_def_id(),
|
||||||
opaque_def_id: opaque_ty_def_id.to_def_id(),
|
opaque_def_id: opaque_ty_def_id.to_def_id(),
|
||||||
}),
|
}),
|
||||||
|
@ -313,9 +311,8 @@ fn associated_type_for_impl_trait_in_impl(
|
||||||
impl_assoc_ty.def_ident_span(Some(span));
|
impl_assoc_ty.def_ident_span(Some(span));
|
||||||
|
|
||||||
impl_assoc_ty.associated_item(ty::AssocItem {
|
impl_assoc_ty.associated_item(ty::AssocItem {
|
||||||
name: kw::Empty,
|
|
||||||
kind: ty::AssocKind::Type {
|
kind: ty::AssocKind::Type {
|
||||||
opt_rpitit_info: Some(ImplTraitInTraitData::Impl {
|
data: ty::AssocTypeData::Rpitit(ImplTraitInTraitData::Impl {
|
||||||
fn_def_id: impl_fn_def_id.to_def_id(),
|
fn_def_id: impl_fn_def_id.to_def_id(),
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
|
|
@ -521,7 +521,7 @@ fn projection_to_path_segment<'tcx>(
|
||||||
let item = cx.tcx.associated_item(def_id);
|
let item = cx.tcx.associated_item(def_id);
|
||||||
let generics = cx.tcx.generics_of(def_id);
|
let generics = cx.tcx.generics_of(def_id);
|
||||||
PathSegment {
|
PathSegment {
|
||||||
name: item.name,
|
name: item.name(),
|
||||||
args: GenericArgs::AngleBracketed {
|
args: GenericArgs::AngleBracketed {
|
||||||
args: clean_middle_generic_args(
|
args: clean_middle_generic_args(
|
||||||
cx,
|
cx,
|
||||||
|
@ -1340,7 +1340,7 @@ pub(crate) fn clean_impl_item<'tcx>(
|
||||||
pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocContext<'_>) -> Item {
|
pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocContext<'_>) -> Item {
|
||||||
let tcx = cx.tcx;
|
let tcx = cx.tcx;
|
||||||
let kind = match assoc_item.kind {
|
let kind = match assoc_item.kind {
|
||||||
ty::AssocKind::Const => {
|
ty::AssocKind::Const { .. } => {
|
||||||
let ty = clean_middle_ty(
|
let ty = clean_middle_ty(
|
||||||
ty::Binder::dummy(tcx.type_of(assoc_item.def_id).instantiate_identity()),
|
ty::Binder::dummy(tcx.type_of(assoc_item.def_id).instantiate_identity()),
|
||||||
cx,
|
cx,
|
||||||
|
@ -1374,7 +1374,7 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::AssocKind::Fn { has_self } => {
|
ty::AssocKind::Fn { has_self, .. } => {
|
||||||
let mut item = inline::build_function(cx, assoc_item.def_id);
|
let mut item = inline::build_function(cx, assoc_item.def_id);
|
||||||
|
|
||||||
if has_self {
|
if has_self {
|
||||||
|
@ -1413,7 +1413,7 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::AssocKind::Type { .. } => {
|
ty::AssocKind::Type { .. } => {
|
||||||
let my_name = assoc_item.name;
|
let my_name = assoc_item.name();
|
||||||
|
|
||||||
fn param_eq_arg(param: &GenericParamDef, arg: &GenericArg) -> bool {
|
fn param_eq_arg(param: &GenericParamDef, arg: &GenericArg) -> bool {
|
||||||
match (¶m.kind, arg) {
|
match (¶m.kind, arg) {
|
||||||
|
@ -1554,7 +1554,7 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Item::from_def_id_and_parts(assoc_item.def_id, Some(assoc_item.name), kind, cx)
|
Item::from_def_id_and_parts(assoc_item.def_id, Some(assoc_item.name()), kind, cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn first_non_private_clean_path<'tcx>(
|
fn first_non_private_clean_path<'tcx>(
|
||||||
|
@ -2223,7 +2223,7 @@ pub(crate) fn clean_middle_ty<'tcx>(
|
||||||
|
|
||||||
Type::QPath(Box::new(QPathData {
|
Type::QPath(Box::new(QPathData {
|
||||||
assoc: PathSegment {
|
assoc: PathSegment {
|
||||||
name: cx.tcx.associated_item(def_id).name,
|
name: cx.tcx.associated_item(def_id).name(),
|
||||||
args: GenericArgs::AngleBracketed {
|
args: GenericArgs::AngleBracketed {
|
||||||
args: clean_middle_generic_args(
|
args: clean_middle_generic_args(
|
||||||
cx,
|
cx,
|
||||||
|
|
|
@ -2504,7 +2504,7 @@ impl Impl {
|
||||||
self.trait_
|
self.trait_
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|t| t.def_id())
|
.map(|t| t.def_id())
|
||||||
.map(|did| tcx.provided_trait_methods(did).map(|meth| meth.name).collect())
|
.map(|did| tcx.provided_trait_methods(did).map(|meth| meth.name()).collect())
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -111,8 +111,8 @@ impl<'tcx> LateLintPass<'tcx> for AssigningClones {
|
||||||
// Only suggest if `clone_from`/`clone_into` is explicitly implemented
|
// Only suggest if `clone_from`/`clone_into` is explicitly implemented
|
||||||
&& resolved_assoc_items.in_definition_order().any(|assoc|
|
&& resolved_assoc_items.in_definition_order().any(|assoc|
|
||||||
match which_trait {
|
match which_trait {
|
||||||
CloneTrait::Clone => assoc.name == sym::clone_from,
|
CloneTrait::Clone => assoc.name() == sym::clone_from,
|
||||||
CloneTrait::ToOwned => assoc.name.as_str() == "clone_into",
|
CloneTrait::ToOwned => assoc.name().as_str() == "clone_into",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
&& !clone_source_borrows_from_dest(cx, lhs, rhs.span)
|
&& !clone_source_borrows_from_dest(cx, lhs, rhs.span)
|
||||||
|
|
|
@ -24,7 +24,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &'_ Expr<'_>, self_expr: &'_ Exp
|
||||||
&& let Ok(Some(fn_def)) = Instance::try_resolve(cx.tcx, cx.typing_env(), id, args)
|
&& let Ok(Some(fn_def)) = Instance::try_resolve(cx.tcx, cx.typing_env(), id, args)
|
||||||
// find the provided definition of Iterator::last
|
// find the provided definition of Iterator::last
|
||||||
&& let Some(item) = cx.tcx.get_diagnostic_item(sym::Iterator)
|
&& let Some(item) = cx.tcx.get_diagnostic_item(sym::Iterator)
|
||||||
&& let Some(last_def) = cx.tcx.provided_trait_methods(item).find(|m| m.name.as_str() == "last")
|
&& let Some(last_def) = cx.tcx.provided_trait_methods(item).find(|m| m.name().as_str() == "last")
|
||||||
// if the resolved method is the same as the provided definition
|
// if the resolved method is the same as the provided definition
|
||||||
&& fn_def.def_id() == last_def.def_id
|
&& fn_def.def_id() == last_def.def_id
|
||||||
{
|
{
|
||||||
|
|
|
@ -81,7 +81,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingTraitMethods {
|
||||||
cx,
|
cx,
|
||||||
MISSING_TRAIT_METHODS,
|
MISSING_TRAIT_METHODS,
|
||||||
cx.tcx.def_span(item.owner_id),
|
cx.tcx.def_span(item.owner_id),
|
||||||
format!("missing trait method provided by default: `{}`", assoc.name),
|
format!("missing trait method provided by default: `{}`", assoc.name()),
|
||||||
|diag| {
|
|diag| {
|
||||||
diag.span_help(cx.tcx.def_span(assoc.def_id), "implement the method");
|
diag.span_help(cx.tcx.def_span(assoc.def_id), "implement the method");
|
||||||
},
|
},
|
||||||
|
|
|
@ -85,7 +85,7 @@ impl<'tcx> LateLintPass<'tcx> for SameNameMethod {
|
||||||
.associated_items(did)
|
.associated_items(did)
|
||||||
.in_definition_order()
|
.in_definition_order()
|
||||||
.filter(|assoc_item| assoc_item.is_fn())
|
.filter(|assoc_item| assoc_item.is_fn())
|
||||||
.map(|assoc_item| assoc_item.name)
|
.map(|assoc_item| assoc_item.name())
|
||||||
.collect()
|
.collect()
|
||||||
} else {
|
} else {
|
||||||
BTreeSet::new()
|
BTreeSet::new()
|
||||||
|
|
|
@ -322,7 +322,7 @@ impl UnconditionalRecursion {
|
||||||
.in_definition_order()
|
.in_definition_order()
|
||||||
// We're not interested in foreign implementations of the `Default` trait.
|
// We're not interested in foreign implementations of the `Default` trait.
|
||||||
.find(|item| {
|
.find(|item| {
|
||||||
item.is_fn() && item.def_id.is_local() && item.name == kw::Default
|
item.is_fn() && item.def_id.is_local() && item.name() == kw::Default
|
||||||
})
|
})
|
||||||
&& let Some(body_node) = cx.tcx.hir_get_if_local(assoc_item.def_id)
|
&& let Some(body_node) = cx.tcx.hir_get_if_local(assoc_item.def_id)
|
||||||
&& let Some(body_id) = body_node.body_id()
|
&& let Some(body_id) = body_node.body_id()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue