1
Fork 0

Auto merge of #93938 - BoxyUwU:fix_res_self_ty, r=lcnr

Make `Res::SelfTy` a struct variant and update docs

I found pattern matching on a `(Option<DefId>, Option<(DefId, bool)>)` to not be super readable, additionally the doc comments on the types in a tuple variant aren't visible anywhere at use sites as far as I can tell (using rust analyzer + vscode)

The docs incorrectly assumed that the `DefId` in `Option<(DefId, bool)>` would only ever be for an impl item and I also found the code examples to be somewhat unclear about which `DefId` was being talked about.

r? `@lcnr` since you reviewed the last PR changing these docs
This commit is contained in:
bors 2022-02-14 12:26:43 +00:00
commit b321742c6c
27 changed files with 102 additions and 83 deletions

View file

@ -266,59 +266,67 @@ pub enum Res<Id = hir::HirId> {
///
/// **Belongs to the type namespace.**
PrimTy(hir::PrimTy),
/// The `Self` type, optionally with the trait it is associated with
/// and optionally with the [`DefId`] of the impl it is associated with.
/// The `Self` type, optionally with the [`DefId`] of the trait it belongs to and
/// optionally with the [`DefId`] of the item introducing the `Self` type alias.
///
/// **Belongs to the type namespace.**
///
/// For example, the `Self` in
///
/// Examples:
/// ```
/// struct Bar(Box<Self>);
/// // `Res::SelfTy { trait_: None, alias_of: Some(Bar) }`
///
/// trait Foo {
/// fn foo() -> Box<Self>;
/// // `Res::SelfTy { trait_: Some(Foo), alias_of: None }`
/// }
/// ```
///
/// would have the [`DefId`] of `Foo` associated with it. The `Self` in
///
/// ```
/// struct Bar;
///
/// impl Bar {
/// fn new() -> Self { Bar }
/// fn blah() {
/// let _: Self;
/// // `Res::SelfTy { trait_: None, alias_of: Some(::{impl#0}) }`
/// }
/// }
/// ```
///
/// would have the [`DefId`] of the impl associated with it. Finally, the `Self` in
///
/// ```
/// impl Foo for Bar {
/// fn foo() -> Box<Self> { Box::new(Bar) }
/// fn foo() -> Box<Self> {
/// // `Res::SelfTy { trait_: Some(Foo), alias_of: Some(::{impl#1}) }`
/// let _: Self;
/// // `Res::SelfTy { trait_: Some(Foo), alias_of: Some(::{impl#1}) }`
///
/// todo!()
/// }
/// }
/// ```
///
/// would have both the [`DefId`] of `Foo` and the [`DefId`] of the impl
/// associated with it.
///
/// *See also [`Res::SelfCtor`].*
///
/// -----
///
/// HACK(min_const_generics): impl self types also have an optional requirement to **not** mention
/// HACK(min_const_generics): self types also have an optional requirement to **not** mention
/// any generic parameters to allow the following with `min_const_generics`:
/// ```
/// impl Foo { fn test() -> [u8; std::mem::size_of::<Self>()] { todo!() } }
///
/// struct Bar([u8; baz::<Self>()]);
/// const fn baz<T>() -> usize { 10 }
/// ```
/// We do however allow `Self` in repeat expression even if it is generic to not break code
/// which already works on stable while causing the `const_evaluatable_unchecked` future compat lint.
///
/// FIXME(generic_const_exprs): Remove this bodge once that feature is stable.
SelfTy(
/// Optionally, the trait associated with this `Self` type.
Option<DefId>,
/// Optionally, the impl associated with this `Self` type.
Option<(DefId, bool)>,
),
/// which already works on stable while causing the `const_evaluatable_unchecked` future compat lint:
/// ```
/// fn foo<T>() {
/// let _bar = [1_u8; std::mem::size_of::<*mut T>()];
/// }
/// ```
// FIXME(generic_const_exprs): Remove this bodge once that feature is stable.
SelfTy {
/// The trait this `Self` is a generic arg for.
trait_: Option<DefId>,
/// The item introducing the `Self` type alias. Can be used in the `type_of` query
/// to get the underlying type. Additionally whether the `Self` type is disallowed
/// from mentioning generics (i.e. when used in an anonymous constant).
alias_to: Option<(DefId, bool)>,
},
/// A tool attribute module; e.g., the `rustfmt` in `#[rustfmt::skip]`.
///
/// **Belongs to the type namespace.**
@ -550,7 +558,7 @@ impl<Id> Res<Id> {
Res::Local(..)
| Res::PrimTy(..)
| Res::SelfTy(..)
| Res::SelfTy { .. }
| Res::SelfCtor(..)
| Res::ToolMod
| Res::NonMacroAttr(..)
@ -573,7 +581,7 @@ impl<Id> Res<Id> {
Res::SelfCtor(..) => "self constructor",
Res::PrimTy(..) => "builtin type",
Res::Local(..) => "local variable",
Res::SelfTy(..) => "self type",
Res::SelfTy { .. } => "self type",
Res::ToolMod => "tool module",
Res::NonMacroAttr(attr_kind) => attr_kind.descr(),
Res::Err => "unresolved item",
@ -596,7 +604,7 @@ impl<Id> Res<Id> {
Res::SelfCtor(id) => Res::SelfCtor(id),
Res::PrimTy(id) => Res::PrimTy(id),
Res::Local(id) => Res::Local(map(id)),
Res::SelfTy(a, b) => Res::SelfTy(a, b),
Res::SelfTy { trait_, alias_to } => Res::SelfTy { trait_, alias_to },
Res::ToolMod => Res::ToolMod,
Res::NonMacroAttr(attr_kind) => Res::NonMacroAttr(attr_kind),
Res::Err => Res::Err,
@ -620,7 +628,7 @@ impl<Id> Res<Id> {
pub fn ns(&self) -> Option<Namespace> {
match self {
Res::Def(kind, ..) => kind.ns(),
Res::PrimTy(..) | Res::SelfTy(..) | Res::ToolMod => Some(Namespace::TypeNS),
Res::PrimTy(..) | Res::SelfTy { .. } | Res::ToolMod => Some(Namespace::TypeNS),
Res::SelfCtor(..) | Res::Local(..) => Some(Namespace::ValueNS),
Res::NonMacroAttr(..) => Some(Namespace::MacroNS),
Res::Err => None,

View file

@ -640,9 +640,8 @@ impl<'hir> WhereBoundPredicate<'hir> {
_ => return false,
};
match path.res {
Res::Def(DefKind::TyParam, def_id) | Res::SelfTy(Some(def_id), None) => {
def_id == param_def_id
}
Res::Def(DefKind::TyParam, def_id)
| Res::SelfTy { trait_: Some(def_id), alias_to: None } => def_id == param_def_id,
_ => false,
}
}