Move opt_rpitit_info field to hir::AssocKind::Type.

From `hir::AssocItem`.
This commit is contained in:
Nicholas Nethercote 2025-04-11 16:50:20 +10:00
parent ce2aa97cd6
commit b26f3d4347
28 changed files with 103 additions and 91 deletions

View File

@ -449,7 +449,7 @@ fn best_definition_site_of_opaque<'tcx>(
return Some(span); 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() { for &assoc_item in assoc_items.in_definition_order() {
match assoc_item.kind { 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 trait_args = GenericArgs::identity_for_item(tcx, def_id);
let _: Result<_, rustc_errors::ErrorGuaranteed> = check_type_bounds( let _: Result<_, rustc_errors::ErrorGuaranteed> = check_type_bounds(
tcx, tcx,
@ -953,7 +953,7 @@ fn check_impl_items_against_trait<'tcx>(
); );
} }
ty::AssocKind::Const => {} ty::AssocKind::Const => {}
ty::AssocKind::Type => {} ty::AssocKind::Type { .. } => {}
} }
} }

View File

@ -44,7 +44,7 @@ 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),
} }
} }
@ -1703,7 +1703,7 @@ fn compare_generic_param_kinds<'tcx>(
trait_item: ty::AssocItem, trait_item: ty::AssocItem,
delay: bool, delay: bool,
) -> Result<(), ErrorGuaranteed> { ) -> 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| { let ty_const_params_of = |def_id| {
tcx.generics_of(def_id).own_params.iter().filter(|param| { tcx.generics_of(def_id).own_params.iter().filter(|param| {
@ -2235,16 +2235,19 @@ fn param_env_with_gat_bounds<'tcx>(
// of the RPITITs associated with the same body. This is because checking // of the RPITITs associated with the same body. This is because checking
// the item bounds of RPITITs often involves nested RPITITs having to prove // the item bounds of RPITITs often involves nested RPITITs having to prove
// bounds about themselves. // bounds about themselves.
let impl_tys_to_install = match impl_ty.opt_rpitit_info { let impl_tys_to_install = match impl_ty.kind {
None => vec![impl_ty], ty::AssocKind::Type {
Some( opt_rpitit_info:
ty::ImplTraitInTraitData::Impl { fn_def_id } Some(
| ty::ImplTraitInTraitData::Trait { fn_def_id, .. }, ty::ImplTraitInTraitData::Impl { fn_def_id }
) => tcx | ty::ImplTraitInTraitData::Trait { fn_def_id, .. },
),
} => tcx
.associated_types_for_impl_traits_in_associated_fn(fn_def_id) .associated_types_for_impl_traits_in_associated_fn(fn_def_id)
.iter() .iter()
.map(|def_id| tcx.associated_item(*def_id)) .map(|def_id| tcx.associated_item(*def_id))
.collect(), .collect(),
_ => vec![impl_ty],
}; };
for impl_ty in impl_tys_to_install { for impl_ty in impl_tys_to_install {

View File

@ -499,7 +499,7 @@ fn suggestion_signature<'tcx>(
tcx.predicates_of(assoc.def_id).instantiate_own(tcx, args), tcx.predicates_of(assoc.def_id).instantiate_own(tcx, args),
assoc, assoc,
), ),
ty::AssocKind::Type => { ty::AssocKind::Type { .. } => {
let (generics, where_clauses) = bounds_from_generic_predicates( let (generics, where_clauses) = bounds_from_generic_predicates(
tcx, tcx,
tcx.predicates_of(assoc.def_id).instantiate_own(tcx, args), tcx.predicates_of(assoc.def_id).instantiate_own(tcx, args),

View File

@ -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_def_id = gat_item.def_id.expect_local();
let gat_item = tcx.associated_item(gat_def_id); 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 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; continue;
} }
let gat_generics = tcx.generics_of(gat_def_id); let gat_generics = tcx.generics_of(gat_def_id);
@ -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 // 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 // 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 // the param-env here. This allows this GAT to propagate missing bounds
// to other GATs. // to other GATs.
@ -1101,7 +1101,7 @@ fn check_associated_item(
); );
check_method_receiver(wfcx, hir_sig, item, self_ty) check_method_receiver(wfcx, hir_sig, item, self_ty)
} }
ty::AssocKind::Type => { ty::AssocKind::Type { .. } => {
if let ty::AssocItemContainer::Trait = item.container { if let ty::AssocItemContainer::Trait = item.container {
check_associated_type_bounds(wfcx, item, span) check_associated_type_bounds(wfcx, item, span)
} }

View File

@ -36,7 +36,7 @@ pub(super) fn find_opaque_ty_constraints_for_impl_trait_in_assoc_type(
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
ty::AssocKind::Type => {} ty::AssocKind::Type { .. } => {}
} }
} }

View File

@ -4,7 +4,7 @@ use GenericArgsInfo::*;
use rustc_errors::codes::*; use rustc_errors::codes::*;
use rustc_errors::{Applicability, Diag, Diagnostic, EmissionGuarantee, MultiSpan, pluralize}; use rustc_errors::{Applicability, Diag, Diagnostic, EmissionGuarantee, MultiSpan, pluralize};
use rustc_hir as hir; 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 rustc_span::def_id::DefId;
use tracing::debug; use tracing::debug;
@ -486,7 +486,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
let items: &AssocItems = self.tcx.associated_items(self.def_id); let items: &AssocItems = self.tcx.associated_items(self.def_id);
items items
.in_definition_order() .in_definition_order()
.filter(|item| item.kind == AssocKind::Type) .filter(|item| item.is_type())
.filter(|item| { .filter(|item| {
!self !self
.gen_args .gen_args

View File

@ -201,7 +201,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
tcx.associated_items(pred.trait_ref.def_id) tcx.associated_items(pred.trait_ref.def_id)
.in_definition_order() .in_definition_order()
// We only care about associated types. // 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. // No RPITITs -- they're not dyn-compatible for now.
.filter(|item| !item.is_impl_trait_in_trait()) .filter(|item| !item.is_impl_trait_in_trait())
// If the associated type has a `where Self: Sized` bound, // If the associated type has a `where Self: Sized` bound,

View File

@ -1733,7 +1733,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
.any(|i| { .any(|i| {
i.kind.namespace() == Namespace::TypeNS i.kind.namespace() == Namespace::TypeNS
&& i.ident(tcx).normalize_to_macros_2_0() == assoc_ident && i.ident(tcx).normalize_to_macros_2_0() == assoc_ident
&& matches!(i.kind, ty::AssocKind::Type) && i.is_type()
}) })
// Consider only accessible traits // Consider only accessible traits
&& tcx.visibility(*trait_def_id) && tcx.visibility(*trait_def_id)

View File

@ -112,7 +112,7 @@ pub(crate) fn enforce_impl_lifetime_params_are_constrained(
.flat_map(|def_id| { .flat_map(|def_id| {
let item = tcx.associated_item(def_id); let item = tcx.associated_item(def_id);
match item.kind { match item.kind {
ty::AssocKind::Type => { ty::AssocKind::Type { .. } => {
if item.defaultness(tcx).has_value() { if item.defaultness(tcx).has_value() {
cgp::parameters_for(tcx, tcx.type_of(def_id).instantiate_identity(), true) cgp::parameters_for(tcx, tcx.type_of(def_id).instantiate_identity(), true)
} else { } else {

View File

@ -1671,15 +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: item: AssocItem { def_id, name: _, kind: _, container: _, trait_item_def_id: _ },
AssocItem {
def_id,
name: _,
kind: _,
container: _,
trait_item_def_id: _,
opt_rpitit_info: _,
},
kind: _, kind: _,
import_ids: _, import_ids: _,
autoderefs: _, autoderefs: _,
@ -2253,7 +2245,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
match self.mode { match self.mode {
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,
}, },
} }

View File

@ -1342,12 +1342,17 @@ impl<'a> CrateMetadataRef<'a> {
DefKind::AssocFn => { DefKind::AssocFn => {
ty::AssocKind::Fn { has_self: self.get_fn_has_self_parameter(id, sess) } ty::AssocKind::Fn { has_self: self.get_fn_has_self_parameter(id, sess) }
} }
DefKind::AssocTy => ty::AssocKind::Type, DefKind::AssocTy => ty::AssocKind::Type {
opt_rpitit_info: self
.root
.tables
.opt_rpitit_info
.get(self, id)
.map(|d| d.decode(self)),
},
_ => 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();
let opt_rpitit_info =
self.root.tables.opt_rpitit_info.get(self, id).map(|d| d.decode(self));
ty::AssocItem { ty::AssocItem {
name, name,
@ -1355,7 +1360,6 @@ impl<'a> CrateMetadataRef<'a> {
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),
container, container,
opt_rpitit_info,
} }
} }

View File

@ -1691,7 +1691,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
match item.container { match item.container {
AssocItemContainer::Trait => { AssocItemContainer::Trait => {
if let ty::AssocKind::Type = item.kind { if item.is_type() {
self.encode_explicit_item_bounds(def_id); self.encode_explicit_item_bounds(def_id);
self.encode_explicit_item_self_bounds(def_id); self.encode_explicit_item_self_bounds(def_id);
if tcx.is_conditionally_const(def_id) { if tcx.is_conditionally_const(def_id) {
@ -1706,7 +1706,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
} }
} }
} }
if let Some(rpitit_info) = item.opt_rpitit_info { if let ty::AssocKind::Type { opt_rpitit_info: Some(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!(

View File

@ -25,11 +25,6 @@ pub struct AssocItem {
/// If this is an item in an impl of a trait then this is the `DefId` of /// If this is an item in an impl of a trait then this is the `DefId` of
/// the associated item on the trait that this implements. /// the associated item on the trait that this implements.
pub trait_item_def_id: Option<DefId>, pub trait_item_def_id: Option<DefId>,
/// `Some` if the associated item (an associated type) comes from the
/// return-position `impl Trait` in trait desugaring. The `ImplTraitInTraitData`
/// provides additional information about its source.
pub opt_rpitit_info: Option<ty::ImplTraitInTraitData>,
} }
impl AssocItem { impl AssocItem {
@ -81,7 +76,7 @@ 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 => {
format!( format!(
"const {}: {:?};", "const {}: {:?};",
@ -97,10 +92,14 @@ impl AssocItem {
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",
} }
} }
pub fn is_type(&self) -> bool {
matches!(self.kind, ty::AssocKind::Type { .. })
}
pub fn is_fn(&self) -> bool { pub fn is_fn(&self) -> bool {
matches!(self.kind, ty::AssocKind::Fn { .. }) matches!(self.kind, ty::AssocKind::Fn { .. })
} }
@ -113,12 +112,12 @@ impl AssocItem {
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 {
self.opt_rpitit_info.is_some() matches!(self.kind, AssocKind::Type { opt_rpitit_info: Some(_) })
} }
/// Returns true if: /// Returns true if:
@ -143,14 +142,21 @@ impl AssocItem {
#[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,
Fn { has_self: bool }, Fn {
Type, has_self: bool,
},
Type {
/// `Some` if the associated type comes from an RPITIT. The
/// `ImplTraitInTraitData` provides additional information about its
/// source.
opt_rpitit_info: Option<ty::ImplTraitInTraitData>,
},
} }
impl AssocKind { impl AssocKind {
pub fn namespace(&self) -> Namespace { pub fn namespace(&self) -> Namespace {
match *self { match *self {
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,
} }
} }
@ -159,7 +165,7 @@ impl AssocKind {
match self { match self {
AssocKind::Const => DefKind::AssocConst, AssocKind::Const => DefKind::AssocConst,
AssocKind::Fn { .. } => DefKind::AssocFn, AssocKind::Fn { .. } => DefKind::AssocFn,
AssocKind::Type => DefKind::AssocTy, AssocKind::Type { .. } => DefKind::AssocTy,
} }
} }
} }
@ -170,7 +176,7 @@ impl std::fmt::Display for AssocKind {
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"),
} }
} }
} }

View File

@ -464,7 +464,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
fn associated_type_def_ids(self, def_id: DefId) -> impl IntoIterator<Item = DefId> { fn associated_type_def_ids(self, def_id: DefId) -> impl IntoIterator<Item = DefId> {
self.associated_items(def_id) self.associated_items(def_id)
.in_definition_order() .in_definition_order()
.filter(|assoc_item| matches!(assoc_item.kind, ty::AssocKind::Type)) .filter(|assoc_item| assoc_item.is_type())
.map(|assoc_item| assoc_item.def_id) .map(|assoc_item| assoc_item.def_id)
} }

View File

@ -1610,8 +1610,10 @@ impl<'tcx> TyCtxt<'tcx> {
/// return-position `impl Trait` from a trait, then provide the source info /// return-position `impl Trait` from a trait, then provide the source info
/// 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)
self.associated_item(def_id).opt_rpitit_info && let AssocKind::Type { opt_rpitit_info } = self.associated_item(def_id).kind
{
opt_rpitit_info
} else { } else {
None None
} }

View File

@ -734,7 +734,7 @@ impl<'tcx> Ty<'tcx> {
.map(|principal| { .map(|principal| {
tcx.associated_items(principal.def_id()) tcx.associated_items(principal.def_id())
.in_definition_order() .in_definition_order()
.filter(|item| item.kind == ty::AssocKind::Type) .filter(|item| item.is_type())
.filter(|item| !item.is_impl_trait_in_trait()) .filter(|item| !item.is_impl_trait_in_trait())
.filter(|item| !tcx.generics_require_sized_self(item.def_id)) .filter(|item| !tcx.generics_require_sized_self(item.def_id))
.count() .count()

View File

@ -240,7 +240,7 @@ fn trait_object_ty<'tcx>(tcx: TyCtxt<'tcx>, poly_trait_ref: ty::PolyTraitRef<'tc
.flat_map(|super_poly_trait_ref| { .flat_map(|super_poly_trait_ref| {
tcx.associated_items(super_poly_trait_ref.def_id()) tcx.associated_items(super_poly_trait_ref.def_id())
.in_definition_order() .in_definition_order()
.filter(|item| item.kind == ty::AssocKind::Type) .filter(|item| item.is_type())
.filter(|item| !tcx.generics_require_sized_self(item.def_id)) .filter(|item| !tcx.generics_require_sized_self(item.def_id))
.map(move |assoc_ty| { .map(move |assoc_ty| {
super_poly_trait_ref.map_bound(|super_trait_ref| { super_poly_trait_ref.map_bound(|super_trait_ref| {

View File

@ -894,12 +894,14 @@ impl<'tcx> Stable<'tcx> for rustc_session::cstore::ForeignModule {
impl<'tcx> Stable<'tcx> for ty::AssocKind { 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;
match *self { match *self {
ty::AssocKind::Const => AssocKind::Const, ty::AssocKind::Const => AssocKind::Const,
ty::AssocKind::Fn { has_self } => AssocKind::Fn { has_self }, ty::AssocKind::Fn { has_self } => AssocKind::Fn { has_self },
ty::AssocKind::Type => AssocKind::Type, ty::AssocKind::Type { opt_rpitit_info } => AssocKind::Type {
opt_rpitit_info: opt_rpitit_info.map(|rpitit| rpitit.stable(tables)),
},
} }
} }
} }
@ -926,7 +928,6 @@ impl<'tcx> Stable<'tcx> for ty::AssocItem {
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)),
opt_rpitit_info: self.opt_rpitit_info.map(|rpitit| rpitit.stable(tables)),
} }
} }
} }

View File

@ -25,7 +25,7 @@ impl Display for AssocKind {
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"),
} }
} }
} }

View File

@ -1585,18 +1585,20 @@ pub struct AssocItem {
/// If this is an item in an impl of a trait then this is the `DefId` of /// If this is an item in an impl of a trait then this is the `DefId` of
/// the associated item on the trait that this implements. /// the associated item on the trait that this implements.
pub trait_item_def_id: Option<AssocDef>, pub trait_item_def_id: Option<AssocDef>,
/// `Some` if the associated item (an associated type) comes from the
/// return-position `impl Trait` in trait desugaring. The `ImplTraitInTraitData`
/// provides additional information about its source.
pub opt_rpitit_info: Option<ImplTraitInTraitData>,
} }
#[derive(Clone, Debug, Eq, PartialEq, Serialize)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum AssocKind { pub enum AssocKind {
Const, Const,
Fn { has_self: bool }, Fn {
Type, has_self: bool,
},
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)]
@ -1613,6 +1615,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 {
self.opt_rpitit_info.is_some() matches!(self.kind, AssocKind::Type { opt_rpitit_info: Some(_) })
} }
} }

View File

@ -2337,7 +2337,7 @@ impl<'tcx> ObligationCause<'tcx> {
ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Fn { .. }, .. } => { ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Fn { .. }, .. } => {
ObligationCauseFailureCode::MethodCompat { span, subdiags } ObligationCauseFailureCode::MethodCompat { span, subdiags }
} }
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, .. } => {
@ -2401,7 +2401,7 @@ impl<'tcx> ObligationCause<'tcx> {
ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Fn { .. }, .. } => { ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Fn { .. }, .. } => {
"method type is compatible with trait" "method type is compatible with trait"
} }
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, .. } => {
@ -2425,7 +2425,9 @@ impl IntoDiagArg for ObligationCauseAsDiagArg<'_> {
ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Fn { .. }, .. } => { ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Fn { .. }, .. } => {
"method_compat" "method_compat"
} }
ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Type, .. } => "type_compat", ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Type { .. }, .. } => {
"type_compat"
}
ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Const, .. } => { ObligationCauseCode::CompareImplItem { kind: ty::AssocKind::Const, .. } => {
"const_compat" "const_compat"
} }

View File

@ -352,7 +352,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
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.
ty::AssocKind::Type => ("refer to the", "type"), ty::AssocKind::Type { .. } => ("refer to the", "type"),
}; };
// Replace the more general E0283 with a more specific error // Replace the more general E0283 with a more specific error

View File

@ -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`",

View File

@ -188,7 +188,7 @@ fn bounds_reference_self(tcx: TyCtxt<'_>, trait_def_id: DefId) -> SmallVec<[Span
tcx.associated_items(trait_def_id) tcx.associated_items(trait_def_id)
.in_definition_order() .in_definition_order()
// We're only looking at associated type bounds // We're only looking at associated type bounds
.filter(|item| item.kind == ty::AssocKind::Type) .filter(|item| item.is_type())
// Ignore GATs with `Self: Sized` // Ignore GATs with `Self: Sized`
.filter(|item| !tcx.generics_require_sized_self(item.def_id)) .filter(|item| !tcx.generics_require_sized_self(item.def_id))
.flat_map(|item| tcx.explicit_item_bounds(item.def_id).iter_identity_copied()) .flat_map(|item| tcx.explicit_item_bounds(item.def_id).iter_identity_copied())
@ -320,7 +320,7 @@ pub fn dyn_compatibility_violations_for_assoc_item(
}) })
.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 {

View File

@ -594,9 +594,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// Associated types that require `Self: Sized` do not show up in the built-in // Associated types that require `Self: Sized` do not show up in the built-in
// implementation of `Trait for dyn Trait`, and can be dropped here. // implementation of `Trait for dyn Trait`, and can be dropped here.
.filter(|item| !tcx.generics_require_sized_self(item.def_id)) .filter(|item| !tcx.generics_require_sized_self(item.def_id))
.filter_map( .filter_map(|item| if item.is_type() { Some(item.def_id) } else { None })
|item| if item.kind == ty::AssocKind::Type { Some(item.def_id) } else { None },
)
.collect(); .collect();
for assoc_type in assoc_types { for assoc_type in assoc_types {

View File

@ -132,7 +132,7 @@ fn associated_item_from_trait_item_ref(trait_item_ref: &hir::TraitItemRef) -> ty
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,
hir::AssocItemKind::Fn { has_self } => ty::AssocKind::Fn { has_self }, hir::AssocItemKind::Fn { has_self } => ty::AssocKind::Fn { has_self },
hir::AssocItemKind::Type => ty::AssocKind::Type, hir::AssocItemKind::Type => ty::AssocKind::Type { opt_rpitit_info: None },
}; };
ty::AssocItem { ty::AssocItem {
@ -141,7 +141,6 @@ fn associated_item_from_trait_item_ref(trait_item_ref: &hir::TraitItemRef) -> ty
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()),
container: ty::AssocItemContainer::Trait, container: ty::AssocItemContainer::Trait,
opt_rpitit_info: None,
} }
} }
@ -150,7 +149,7 @@ fn associated_item_from_impl_item_ref(impl_item_ref: &hir::ImplItemRef) -> ty::A
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,
hir::AssocItemKind::Fn { has_self } => ty::AssocKind::Fn { has_self }, hir::AssocItemKind::Fn { has_self } => ty::AssocKind::Fn { has_self },
hir::AssocItemKind::Type => ty::AssocKind::Type, hir::AssocItemKind::Type => ty::AssocKind::Type { opt_rpitit_info: None },
}; };
ty::AssocItem { ty::AssocItem {
@ -159,7 +158,6 @@ fn associated_item_from_impl_item_ref(impl_item_ref: &hir::ImplItemRef) -> ty::A
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,
container: ty::AssocItemContainer::Impl, container: ty::AssocItemContainer::Impl,
opt_rpitit_info: None,
} }
} }
@ -263,14 +261,15 @@ fn associated_type_for_impl_trait_in_trait(
trait_assoc_ty.associated_item(ty::AssocItem { trait_assoc_ty.associated_item(ty::AssocItem {
name: kw::Empty, name: kw::Empty,
kind: ty::AssocKind::Type, kind: ty::AssocKind::Type {
opt_rpitit_info: Some(ImplTraitInTraitData::Trait {
fn_def_id: fn_def_id.to_def_id(),
opaque_def_id: opaque_ty_def_id.to_def_id(),
}),
},
def_id, def_id,
trait_item_def_id: None, trait_item_def_id: None,
container: ty::AssocItemContainer::Trait, container: ty::AssocItemContainer::Trait,
opt_rpitit_info: Some(ImplTraitInTraitData::Trait {
fn_def_id: fn_def_id.to_def_id(),
opaque_def_id: opaque_ty_def_id.to_def_id(),
}),
}); });
// Copy visility of the containing function. // Copy visility of the containing function.
@ -315,11 +314,14 @@ fn associated_type_for_impl_trait_in_impl(
impl_assoc_ty.associated_item(ty::AssocItem { impl_assoc_ty.associated_item(ty::AssocItem {
name: kw::Empty, name: kw::Empty,
kind: ty::AssocKind::Type, kind: ty::AssocKind::Type {
opt_rpitit_info: Some(ImplTraitInTraitData::Impl {
fn_def_id: impl_fn_def_id.to_def_id(),
}),
},
def_id, def_id,
trait_item_def_id: Some(trait_assoc_def_id), trait_item_def_id: Some(trait_assoc_def_id),
container: ty::AssocItemContainer::Impl, container: ty::AssocItemContainer::Impl,
opt_rpitit_info: Some(ImplTraitInTraitData::Impl { fn_def_id: impl_fn_def_id.to_def_id() }),
}); });
// Copy visility of the containing function. // Copy visility of the containing function.

View File

@ -1412,7 +1412,7 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo
RequiredMethodItem(item) RequiredMethodItem(item)
} }
} }
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 {

View File

@ -315,7 +315,7 @@ fn check<'tcx>(cx: &LateContext<'tcx>, bounds: GenericBounds<'tcx>) {
assocs assocs
.filter_by_name_unhygienic(constraint.ident.name) .filter_by_name_unhygienic(constraint.ident.name)
.next() .next()
.is_some_and(|assoc| assoc.kind == ty::AssocKind::Type) .is_some_and(|assoc| assoc.is_type())
}) })
{ {
emit_lint(cx, poly_trait, bounds, index, implied_constraints, bound); emit_lint(cx, poly_trait, bounds, index, implied_constraints, bound);