Skip to content

Commit

Permalink
Auto merge of #101887 - nnethercote:shrink-Res, r=spastorino
Browse files Browse the repository at this point in the history
Shrink `hir::def::Res`

r? `@spastorino`
  • Loading branch information
bors committed Sep 29, 2022
2 parents 9c56d9d + f07d4ef commit 1bb8d27
Show file tree
Hide file tree
Showing 28 changed files with 225 additions and 186 deletions.
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

0 comments on commit 1bb8d27

Please sign in to comment.