Skip to content
Merged
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