Skip to content

Misc cleanups of generic_arg_infer related HIR logic #142678

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

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 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
2 changes: 1 addition & 1 deletion compiler/rustc_ast_lowering/src/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
);

self.with_parent(const_arg.hir_id, |this| {
intravisit::walk_ambig_const_arg(this, const_arg);
intravisit::walk_const_arg(this, const_arg);
});
}

Expand Down
32 changes: 23 additions & 9 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -407,10 +407,8 @@ impl<'hir> PathSegment<'hir> {
/// that are [just paths](ConstArgKind::Path) (currently just bare const params)
/// versus const args that are literals or have arbitrary computations (e.g., `{ 1 + 3 }`).
///
/// The `Unambig` generic parameter represents whether the position this const is from is
/// unambiguously a const or ambiguous as to whether it is a type or a const. When in an
/// ambiguous context the parameter is instantiated with an uninhabited type making the
/// [`ConstArgKind::Infer`] variant unusable and [`GenericArg::Infer`] is used instead.
/// For an explanation of the `Unambig` generic parameter see the dev-guide:
/// https://rustc-dev-guide.rust-lang.org/hir/ambig-unambig-ty-and-consts.html
#[derive(Clone, Copy, Debug, HashStable_Generic)]
#[repr(C)]
pub struct ConstArg<'hir, Unambig = ()> {
Expand All @@ -429,6 +427,9 @@ impl<'hir> ConstArg<'hir, AmbigArg> {
/// In practice this may mean overriding the [`Visitor::visit_infer`][visit_infer] method on hir visitors, or
/// specifically matching on [`GenericArg::Infer`] when handling generic arguments.
///
/// For an explanation of what it means for a const arg to be ambig or unambig, see the dev-guide:
/// https://rustc-dev-guide.rust-lang.org/hir/ambig-unambig-ty-and-consts.html
///
/// [visit_infer]: [rustc_hir::intravisit::Visitor::visit_infer]
pub fn as_unambig_ct(&self) -> &ConstArg<'hir> {
// SAFETY: `ConstArg` is `repr(C)` and `ConstArgKind` is marked `repr(u8)` so that the
Expand All @@ -444,6 +445,9 @@ impl<'hir> ConstArg<'hir> {
///
/// Functions accepting ambiguous consts will not handle the [`ConstArgKind::Infer`] variant, if
/// infer consts are relevant to you then care should be taken to handle them separately.
///
/// For an explanation of what it means for a const arg to be ambig or unambig, see the dev-guide:
/// https://rustc-dev-guide.rust-lang.org/hir/ambig-unambig-ty-and-consts.html
pub fn try_as_ambig_ct(&self) -> Option<&ConstArg<'hir, AmbigArg>> {
if let ConstArgKind::Infer(_, ()) = self.kind {
return None;
Expand Down Expand Up @@ -475,6 +479,9 @@ impl<'hir, Unambig> ConstArg<'hir, Unambig> {
}

/// See [`ConstArg`].
///
/// For an explanation of the `Unambig` generic parameter see the dev-guide:
/// https://rustc-dev-guide.rust-lang.org/hir/ambig-unambig-ty-and-consts.html
#[derive(Clone, Copy, Debug, HashStable_Generic)]
#[repr(u8, C)]
pub enum ConstArgKind<'hir, Unambig = ()> {
Expand Down Expand Up @@ -3302,10 +3309,8 @@ pub enum AmbigArg {}
#[repr(C)]
/// Represents a type in the `HIR`.
///
/// The `Unambig` generic parameter represents whether the position this type is from is
/// unambiguously a type or ambiguous as to whether it is a type or a const. When in an
/// ambiguous context the parameter is instantiated with an uninhabited type making the
/// [`TyKind::Infer`] variant unusable and [`GenericArg::Infer`] is used instead.
/// For an explanation of the `Unambig` generic parameter see the dev-guide:
/// https://rustc-dev-guide.rust-lang.org/hir/ambig-unambig-ty-and-consts.html
pub struct Ty<'hir, Unambig = ()> {
#[stable_hasher(ignore)]
pub hir_id: HirId,
Expand All @@ -3323,6 +3328,9 @@ impl<'hir> Ty<'hir, AmbigArg> {
/// In practice this may mean overriding the [`Visitor::visit_infer`][visit_infer] method on hir visitors, or
/// specifically matching on [`GenericArg::Infer`] when handling generic arguments.
///
/// For an explanation of what it means for a type to be ambig or unambig, see the dev-guide:
/// https://rustc-dev-guide.rust-lang.org/hir/ambig-unambig-ty-and-consts.html
///
/// [visit_infer]: [rustc_hir::intravisit::Visitor::visit_infer]
pub fn as_unambig_ty(&self) -> &Ty<'hir> {
// SAFETY: `Ty` is `repr(C)` and `TyKind` is marked `repr(u8)` so that the layout is
Expand All @@ -3338,6 +3346,9 @@ impl<'hir> Ty<'hir> {
///
/// Functions accepting ambiguous types will not handle the [`TyKind::Infer`] variant, if
/// infer types are relevant to you then care should be taken to handle them separately.
///
/// For an explanation of what it means for a type to be ambig or unambig, see the dev-guide:
/// https://rustc-dev-guide.rust-lang.org/hir/ambig-unambig-ty-and-consts.html
pub fn try_as_ambig_ty(&self) -> Option<&Ty<'hir, AmbigArg>> {
if let TyKind::Infer(()) = self.kind {
return None;
Expand Down Expand Up @@ -3640,9 +3651,12 @@ pub enum InferDelegationKind {
}

/// The various kinds of types recognized by the compiler.
#[derive(Debug, Clone, Copy, HashStable_Generic)]
///
/// For an explanation of the `Unambig` generic parameter see the dev-guide:
/// https://rustc-dev-guide.rust-lang.org/hir/ambig-unambig-ty-and-consts.html
// SAFETY: `repr(u8)` is required so that `TyKind<()>` and `TyKind<!>` are layout compatible
#[repr(u8, C)]
#[derive(Debug, Clone, Copy, HashStable_Generic)]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why these new derives?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not new I just moved them below all the comments

pub enum TyKind<'hir, Unambig = ()> {
/// Actual type should be inherited from `DefId` signature
InferDelegation(DefId, InferDelegationKind),
Expand Down
32 changes: 22 additions & 10 deletions compiler/rustc_hir/src/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -364,8 +364,8 @@ pub trait Visitor<'v>: Sized {
/// All types are treated as ambiguous types for the purposes of hir visiting in
/// order to ensure that visitors can handle infer vars without it being too error-prone.
///
/// See the doc comments on [`Ty`] for an explanation of what it means for a type to be
/// ambiguous.
/// For an explanation of what it means for a type to be ambig, see the dev-guide:
/// https://rustc-dev-guide.rust-lang.org/hir/ambig-unambig-ty-and-consts.html
///
/// The [`Visitor::visit_infer`] method should be overridden in order to handle infer vars.
fn visit_ty(&mut self, t: &'v Ty<'v, AmbigArg>) -> Self::Result {
Expand All @@ -375,12 +375,12 @@ pub trait Visitor<'v>: Sized {
/// All consts are treated as ambiguous consts for the purposes of hir visiting in
/// order to ensure that visitors can handle infer vars without it being too error-prone.
///
/// See the doc comments on [`ConstArg`] for an explanation of what it means for a const to be
/// ambiguous.
/// For an explanation of what it means for a const arg to be ambig, see the dev-guide:
/// https://rustc-dev-guide.rust-lang.org/hir/ambig-unambig-ty-and-consts.html
///
/// The [`Visitor::visit_infer`] method should be overridden in order to handle infer vars.
fn visit_const_arg(&mut self, c: &'v ConstArg<'v, AmbigArg>) -> Self::Result {
walk_ambig_const_arg(self, c)
walk_const_arg(self, c)
}

#[allow(unused_variables)]
Expand Down Expand Up @@ -516,6 +516,9 @@ pub trait VisitorExt<'v>: Visitor<'v> {
///
/// Named `visit_ty_unambig` instead of `visit_unambig_ty` to aid in discovery
/// by IDes when `v.visit_ty` is written.
///
/// For an explanation of what it means for a type to be unambig, see the dev-guide:
/// https://rustc-dev-guide.rust-lang.org/hir/ambig-unambig-ty-and-consts.html
fn visit_ty_unambig(&mut self, t: &'v Ty<'v>) -> Self::Result {
walk_unambig_ty(self, t)
}
Expand All @@ -524,8 +527,11 @@ pub trait VisitorExt<'v>: Visitor<'v> {
///
/// Named `visit_const_arg_unambig` instead of `visit_unambig_const_arg` to aid in
/// discovery by IDes when `v.visit_const_arg` is written.
///
/// For an explanation of what it means for a const arg to be unambig, see the dev-guide:
/// https://rustc-dev-guide.rust-lang.org/hir/ambig-unambig-ty-and-consts.html
fn visit_const_arg_unambig(&mut self, c: &'v ConstArg<'v>) -> Self::Result {
walk_const_arg(self, c)
walk_unambig_const_arg(self, c)
}
}
impl<'v, V: Visitor<'v>> VisitorExt<'v> for V {}
Expand Down Expand Up @@ -975,17 +981,20 @@ pub fn walk_generic_arg<'v, V: Visitor<'v>>(
}
}

/// For an explanation of what it means for a type to be unambig, see the dev-guide:
/// https://rustc-dev-guide.rust-lang.org/hir/ambig-unambig-ty-and-consts.html
pub fn walk_unambig_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) -> V::Result {
match typ.try_as_ambig_ty() {
Some(ambig_ty) => visitor.visit_ty(ambig_ty),
None => {
let Ty { hir_id, span, kind: _ } = typ;
try_visit!(visitor.visit_id(*hir_id));
visitor.visit_infer(*hir_id, *span, InferKind::Ty(typ))
}
}
}

/// For an explanation of what it means for a type to be ambig, see the dev-guide:
/// https://rustc-dev-guide.rust-lang.org/hir/ambig-unambig-ty-and-consts.html
pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v, AmbigArg>) -> V::Result {
let Ty { hir_id, span: _, kind } = typ;
try_visit!(visitor.visit_id(*hir_id));
Expand Down Expand Up @@ -1038,21 +1047,24 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v, AmbigArg>) -
V::Result::output()
}

pub fn walk_const_arg<'v, V: Visitor<'v>>(
/// For an explanation of what it means for a const arg to be unambig, see the dev-guide:
/// https://rustc-dev-guide.rust-lang.org/hir/ambig-unambig-ty-and-consts.html
pub fn walk_unambig_const_arg<'v, V: Visitor<'v>>(
visitor: &mut V,
const_arg: &'v ConstArg<'v>,
) -> V::Result {
match const_arg.try_as_ambig_ct() {
Some(ambig_ct) => visitor.visit_const_arg(ambig_ct),
None => {
let ConstArg { hir_id, kind: _ } = const_arg;
try_visit!(visitor.visit_id(*hir_id));
visitor.visit_infer(*hir_id, const_arg.span(), InferKind::Const(const_arg))
}
}
}

pub fn walk_ambig_const_arg<'v, V: Visitor<'v>>(
/// For an explanation of what it means for a const arg to be ambig, see the dev-guide:
/// https://rustc-dev-guide.rust-lang.org/hir/ambig-unambig-ty-and-consts.html
pub fn walk_const_arg<'v, V: Visitor<'v>>(
visitor: &mut V,
const_arg: &'v ConstArg<'v, AmbigArg>,
) -> V::Result {
Expand Down
Loading