Skip to content

Shrink hir::def::Res #101887

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 65 additions & 50 deletions compiler/rustc_hir/src/def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -314,89 +314,95 @@ pub enum Res<Id = hir::HirId> {
/// **Belongs to the type namespace.**
PrimTy(hir::PrimTy),

/// 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.
/// The `Self` type, as used within a trait.
///
/// **Belongs to the type namespace.**
///
/// See the examples on [`Res::SelfTyAlias`] for details.
SelfTyParam {
/// The trait this `Self` is a generic parameter for.
trait_: DefId,
},

/// The `Self` type, as used somewhere other than within a trait.
///
/// **Belongs to the type namespace.**
///
/// Examples:
/// ```
/// struct Bar(Box<Self>);
/// // `Res::SelfTy { trait_: None, alias_of: Some(Bar) }`
/// struct Bar(Box<Self>); // SelfTyAlias
///
/// trait Foo {
/// fn foo() -> Box<Self>;
/// // `Res::SelfTy { trait_: Some(Foo), alias_of: None }`
/// fn foo() -> Box<Self>; // SelfTyParam
/// }
///
/// impl Bar {
/// fn blah() {
/// let _: Self;
/// // `Res::SelfTy { trait_: None, alias_of: Some(::{impl#0}) }`
/// let _: Self; // SelfTyAlias
/// }
/// }
///
/// impl Foo for 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}) }`
/// fn foo() -> Box<Self> { // SelfTyAlias
/// let _: Self; // SelfTyAlias
///
/// todo!()
/// }
/// }
/// ```
///
/// *See also [`Res::SelfCtor`].*
///
/// -----
///
/// 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`:
/// ```
/// # struct Foo;
/// 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:
/// ```
/// 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>,
SelfTyAlias {
/// 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)>,
},
/// to get the underlying type.
alias_to: DefId,

/// A tool attribute module; e.g., the `rustfmt` in `#[rustfmt::skip]`.
///
/// **Belongs to the type namespace.**
ToolMod,
/// Whether the `Self` type is disallowed from mentioning generics (i.e. when used in an
/// anonymous constant).
///
/// 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`:
/// ```
/// # struct Foo;
/// 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:
/// ```
/// 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.
forbid_generic: bool,

/// Is this within an `impl Foo for bar`?
is_trait_impl: bool,
},

// Value namespace
/// The `Self` constructor, along with the [`DefId`]
/// of the impl it is associated with.
///
/// **Belongs to the value namespace.**
///
/// *See also [`Res::SelfTy`].*
/// *See also [`Res::SelfTyParam`] and [`Res::SelfTyAlias`].*
SelfCtor(DefId),

/// A local variable or function parameter.
///
/// **Belongs to the value namespace.**
Local(Id),

/// A tool attribute module; e.g., the `rustfmt` in `#[rustfmt::skip]`.
///
/// **Belongs to the type namespace.**
ToolMod,

// Macro namespace
/// An attribute that is *not* implemented via macro.
/// E.g., `#[inline]` and `#[rustfmt::skip]`, which are essentially directives,
Expand Down Expand Up @@ -606,7 +612,8 @@ impl<Id> Res<Id> {

Res::Local(..)
| Res::PrimTy(..)
| Res::SelfTy { .. }
| Res::SelfTyParam { .. }
| Res::SelfTyAlias { .. }
| Res::SelfCtor(..)
| Res::ToolMod
| Res::NonMacroAttr(..)
Expand All @@ -629,7 +636,7 @@ impl<Id> Res<Id> {
Res::SelfCtor(..) => "self constructor",
Res::PrimTy(..) => "builtin type",
Res::Local(..) => "local variable",
Res::SelfTy { .. } => "self type",
Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => "self type",
Res::ToolMod => "tool module",
Res::NonMacroAttr(attr_kind) => attr_kind.descr(),
Res::Err => "unresolved item",
Expand All @@ -652,7 +659,10 @@ 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 { trait_, alias_to } => Res::SelfTy { trait_, alias_to },
Res::SelfTyParam { trait_ } => Res::SelfTyParam { trait_ },
Res::SelfTyAlias { alias_to, forbid_generic, is_trait_impl } => {
Res::SelfTyAlias { alias_to, forbid_generic, is_trait_impl }
}
Res::ToolMod => Res::ToolMod,
Res::NonMacroAttr(attr_kind) => Res::NonMacroAttr(attr_kind),
Res::Err => Res::Err,
Expand All @@ -665,7 +675,10 @@ 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 { trait_, alias_to } => Res::SelfTy { trait_, alias_to },
Res::SelfTyParam { trait_ } => Res::SelfTyParam { trait_ },
Res::SelfTyAlias { alias_to, forbid_generic, is_trait_impl } => {
Res::SelfTyAlias { alias_to, forbid_generic, is_trait_impl }
}
Res::ToolMod => Res::ToolMod,
Res::NonMacroAttr(attr_kind) => Res::NonMacroAttr(attr_kind),
Res::Err => Res::Err,
Expand All @@ -692,7 +705,9 @@ 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::SelfTyParam { .. } | Res::SelfTyAlias { .. } | Res::ToolMod => {
Some(Namespace::TypeNS)
}
Res::SelfCtor(..) | Res::Local(..) => Some(Namespace::ValueNS),
Res::NonMacroAttr(..) => Some(Namespace::MacroNS),
Res::Err => None,
Expand Down
10 changes: 6 additions & 4 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2404,8 +2404,9 @@ impl<'hir> Ty<'hir> {
return None;
};
match path.res {
Res::Def(DefKind::TyParam, def_id)
| Res::SelfTy { trait_: Some(def_id), alias_to: None } => Some((def_id, segment.ident)),
Res::Def(DefKind::TyParam, def_id) | Res::SelfTyParam { trait_: def_id } => {
Some((def_id, segment.ident))
}
_ => None,
}
}
Expand Down Expand Up @@ -3533,9 +3534,10 @@ mod size_asserts {
static_assert_size!(Param<'_>, 32);
static_assert_size!(Pat<'_>, 72);
static_assert_size!(PatKind<'_>, 48);
static_assert_size!(Path<'_>, 48);
static_assert_size!(PathSegment<'_>, 56);
static_assert_size!(Path<'_>, 40);
static_assert_size!(PathSegment<'_>, 48);
static_assert_size!(QPath<'_>, 24);
static_assert_size!(Res, 12);
static_assert_size!(Stmt<'_>, 32);
static_assert_size!(StmtKind<'_>, 16);
static_assert_size!(TraitItem<'_>, 88);
Expand Down
9 changes: 4 additions & 5 deletions compiler/rustc_hir_analysis/src/astconv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1902,7 +1902,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
// Find the type of the associated item, and the trait where the associated
// item is declared.
let bound = match (&qself_ty.kind(), qself_res) {
(_, Res::SelfTy { trait_: Some(_), alias_to: Some((impl_def_id, _)) }) => {
(_, Res::SelfTyAlias { alias_to: impl_def_id, is_trait_impl: true, .. }) => {
// `Self` in an impl of a trait -- we have a concrete self type and a
// trait reference.
let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id) else {
Expand All @@ -1921,8 +1921,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
}
(
&ty::Param(_),
Res::SelfTy { trait_: Some(param_did), alias_to: None }
| Res::Def(DefKind::TyParam, param_did),
Res::SelfTyParam { trait_: param_did } | Res::Def(DefKind::TyParam, param_did),
) => self.find_bound_for_assoc_item(param_did.expect_local(), assoc_ident, span)?,
_ => {
let reported = if variant_resolution.is_some() {
Expand Down Expand Up @@ -2417,7 +2416,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let index = generics.param_def_id_to_index[&def_id.to_def_id()];
tcx.mk_ty_param(index, tcx.hir().ty_param_name(def_id))
}
Res::SelfTy { trait_: Some(_), alias_to: None } => {
Res::SelfTyParam { .. } => {
// `Self` in trait or type alias.
assert_eq!(opt_self_ty, None);
self.prohibit_generics(path.segments.iter(), |err| {
Expand All @@ -2432,7 +2431,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
});
tcx.types.self_param
}
Res::SelfTy { trait_: _, alias_to: Some((def_id, forbid_generic)) } => {
Res::SelfTyAlias { alias_to: def_id, forbid_generic, .. } => {
// `Self` in impl (we know the concrete type).
assert_eq!(opt_self_ty, None);
// Try to evaluate any array length constants.
Expand Down
9 changes: 6 additions & 3 deletions compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -609,9 +609,12 @@ pub(super) fn check_opaque_for_inheriting_lifetimes<'tcx>(
fn visit_ty(&mut self, arg: &'tcx hir::Ty<'tcx>) {
match arg.kind {
hir::TyKind::Path(hir::QPath::Resolved(None, path)) => match &path.segments {
[PathSegment { res: Res::SelfTy { trait_: _, alias_to: impl_ref }, .. }] => {
let impl_ty_name =
impl_ref.map(|(def_id, _)| self.tcx.def_path_str(def_id));
[PathSegment { res: Res::SelfTyParam { .. }, .. }] => {
let impl_ty_name = None;
self.selftys.push((path.span, impl_ty_name));
}
[PathSegment { res: Res::SelfTyAlias { alias_to: def_id, .. }, .. }] => {
let impl_ty_name = Some(self.tcx.def_path_str(*def_id));
self.selftys.push((path.span, impl_ty_name));
}
_ => {}
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_hir_analysis/src/check/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1199,7 +1199,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
_ => bug!("unexpected type: {:?}", ty),
},
Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _)
| Res::SelfTy { .. } => match ty.kind() {
| Res::SelfTyParam { .. }
| Res::SelfTyAlias { .. } => match ty.kind() {
ty::Adt(adt, substs) if !adt.is_enum() => {
Some((adt.non_enum_variant(), adt.did(), substs))
}
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_hir_analysis/src/mem_categorization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,8 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
Res::Def(DefKind::Ctor(CtorOf::Struct, ..), _)
| Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _)
| Res::SelfCtor(..)
| Res::SelfTy { .. } => {
| Res::SelfTyParam { .. }
| Res::SelfTyAlias { .. } => {
// Structs and Unions have only have one variant.
Ok(VariantIdx::new(0))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1021,7 +1021,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
}
// There cannot be inference variables in the self type,
// so there's nothing for us to do here.
Res::SelfTy { .. } => {}
Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => {}
_ => warn!(
"unexpected path: def={:?} substs={:?} path={:?}",
def, substs, path,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,8 @@ impl<'tcx> Visitor<'tcx> for TypeParamSpanVisitor<'tcx> {
[segment]
if matches!(
segment.res,
Res::SelfTy { trait_: _, alias_to: _ }
Res::SelfTyParam { .. }
| Res::SelfTyAlias { .. }
| Res::Def(hir::def::DefKind::TyParam, _)
) =>
{
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_lint/src/internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ fn is_ty_or_ty_ctxt(cx: &LateContext<'_>, path: &Path<'_>) -> Option<String> {
}
}
// Only lint on `&Ty` and `&TyCtxt` if it is used outside of a trait.
Res::SelfTy { trait_: None, alias_to: Some((did, _)) } => {
Res::SelfTyAlias { alias_to: did, is_trait_impl: false, .. } => {
if let ty::Adt(adt, substs) = cx.tcx.type_of(did).kind() {
if let Some(name @ (sym::Ty | sym::TyCtxt)) = cx.tcx.get_diagnostic_name(adt.did())
{
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_lint/src/pass_by_value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ fn path_for_pass_by_value(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> Option<Stri
let path_segment = path.segments.last().unwrap();
return Some(format!("{}{}", name, gen_args(cx, path_segment)));
}
Res::SelfTy { trait_: None, alias_to: Some((did, _)) } => {
Res::SelfTyAlias { alias_to: did, is_trait_impl: false, .. } => {
if let ty::Adt(adt, substs) = cx.tcx.type_of(did).kind() {
if cx.tcx.has_attr(adt.did(), sym::rustc_pass_by_value) {
return Some(cx.tcx.def_path_str_with_substs(adt.did(), substs));
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_middle/src/ty/adt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,8 @@ impl<'tcx> AdtDef<'tcx> {
| Res::Def(DefKind::Union, _)
| Res::Def(DefKind::TyAlias, _)
| Res::Def(DefKind::AssocTy, _)
| Res::SelfTy { .. }
| Res::SelfTyParam { .. }
| Res::SelfTyAlias { .. }
| Res::SelfCtor(..) => self.non_enum_variant(),
_ => bug!("unexpected res {:?} in variant_of_res", res),
}
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_mir_build/src/thir/pattern/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,8 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
| DefKind::AssocTy,
_,
)
| Res::SelfTy { .. }
| Res::SelfTyParam { .. }
| Res::SelfTyAlias { .. }
| Res::SelfCtor(..) => PatKind::Leaf { subpatterns },
_ => {
let pattern_error = match res {
Expand Down
10 changes: 2 additions & 8 deletions compiler/rustc_passes/src/dead.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,14 +102,8 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
}
}
Res::Def(_, def_id) => self.check_def_id(def_id),
Res::SelfTy { trait_: t, alias_to: i } => {
if let Some(t) = t {
self.check_def_id(t);
}
if let Some((i, _)) = i {
self.check_def_id(i);
}
}
Res::SelfTyParam { trait_: t } => self.check_def_id(t),
Res::SelfTyAlias { alias_to: i, .. } => self.check_def_id(i),
Res::ToolMod | Res::NonMacroAttr(..) | Res::Err => {}
}
}
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_privacy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1422,7 +1422,9 @@ struct ObsoleteCheckTypeForPrivatenessVisitor<'a, 'b, 'tcx> {
impl<'a, 'tcx> ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
fn path_is_private_type(&self, path: &hir::Path<'_>) -> bool {
let did = match path.res {
Res::PrimTy(..) | Res::SelfTy { .. } | Res::Err => return false,
Res::PrimTy(..) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } | Res::Err => {
return false;
}
res => res.def_id(),
};

Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_resolve/src/build_reduced_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1010,7 +1010,8 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
_,
)
| Res::Local(..)
| Res::SelfTy { .. }
| Res::SelfTyParam { .. }
| Res::SelfTyAlias { .. }
| Res::SelfCtor(..)
| Res::Err => bug!("unexpected resolution: {:?}", res),
}
Expand Down
Loading