Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit d1a9704

Browse files
committed
Split hir TyKind and ConstArgKind in two
1 parent 684cc2c commit d1a9704

File tree

44 files changed

+509
-368
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+509
-368
lines changed

compiler/rustc_ast_lowering/src/index.rs

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use intravisit::InferKind;
12
use rustc_data_structures::sorted_map::SortedMap;
23
use rustc_hir as hir;
34
use rustc_hir::def_id::{LocalDefId, LocalDefIdMap};
@@ -250,14 +251,6 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
250251
});
251252
}
252253

253-
fn visit_const_arg(&mut self, const_arg: &'hir ConstArg<'hir>) {
254-
self.insert(const_arg.span(), const_arg.hir_id, Node::ConstArg(const_arg));
255-
256-
self.with_parent(const_arg.hir_id, |this| {
257-
intravisit::walk_const_arg(this, const_arg);
258-
});
259-
}
260-
261254
fn visit_expr(&mut self, expr: &'hir Expr<'hir>) {
262255
self.insert(expr.span, expr.hir_id, Node::Expr(expr));
263256

@@ -287,22 +280,41 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
287280
intravisit::walk_path_segment(self, path_segment);
288281
}
289282

290-
fn visit_ty(&mut self, ty: &'hir Ty<'hir>) {
291-
self.insert(ty.span, ty.hir_id, Node::Ty(ty));
283+
fn visit_ty(&mut self, ty: &'hir Ty<'hir, AmbigArg>) {
284+
self.insert(ty.span, ty.hir_id, Node::Ty(ty.as_unambig_ty()));
292285

293286
self.with_parent(ty.hir_id, |this| {
294-
intravisit::walk_ty(this, ty);
287+
intravisit::walk_ambig_ty(this, ty);
295288
});
296289
}
297290

298-
fn visit_infer(&mut self, inf: &'hir InferArg) {
299-
self.insert(inf.span, inf.hir_id, Node::Infer(inf));
291+
fn visit_const_arg(&mut self, const_arg: &'hir ConstArg<'hir, AmbigArg>) {
292+
self.insert(
293+
const_arg.as_unambig_ct().span(),
294+
const_arg.hir_id,
295+
Node::ConstArg(const_arg.as_unambig_ct()),
296+
);
300297

301-
self.with_parent(inf.hir_id, |this| {
302-
intravisit::walk_inf(this, inf);
298+
self.with_parent(const_arg.hir_id, |this| {
299+
intravisit::walk_ambig_const_arg(this, const_arg);
303300
});
304301
}
305302

303+
fn visit_shared_ty_const(
304+
&mut self,
305+
inf_id: HirId,
306+
inf_span: Span,
307+
kind: InferKind<'hir>,
308+
) -> Self::Result {
309+
match kind {
310+
InferKind::Ty(ty) => self.insert(inf_span, inf_id, Node::Ty(ty)),
311+
InferKind::Const(ct) => self.insert(inf_span, inf_id, Node::ConstArg(ct)),
312+
InferKind::Ambig(inf) => self.insert(inf_span, inf_id, Node::Infer(inf)),
313+
}
314+
315+
self.visit_id(inf_id);
316+
}
317+
306318
fn visit_trait_ref(&mut self, tr: &'hir TraitRef<'hir>) {
307319
self.insert(tr.path.span, tr.hir_ref_id, Node::TraitRef(tr));
308320

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1084,7 +1084,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
10841084
ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(lt)),
10851085
ast::GenericArg::Type(ty) => {
10861086
match &ty.kind {
1087-
TyKind::Infer if self.tcx.features().generic_arg_infer() => {
1087+
TyKind::Infer => {
10881088
return GenericArg::Infer(hir::InferArg {
10891089
hir_id: self.lower_node_id(ty.id),
10901090
span: self.lower_span(ty.span),
@@ -1110,15 +1110,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
11101110

11111111
let ct =
11121112
self.lower_const_path_to_const_arg(path, res, ty.id, ty.span);
1113-
return GenericArg::Const(ct);
1113+
return GenericArg::Const(ct.as_ambig_ct());
11141114
}
11151115
}
11161116
}
11171117
_ => {}
11181118
}
1119-
GenericArg::Type(self.lower_ty(ty, itctx))
1119+
GenericArg::Type(self.lower_ty(ty, itctx).as_ambig_ty())
1120+
}
1121+
ast::GenericArg::Const(ct) => {
1122+
GenericArg::Const(self.lower_anon_const_to_const_arg(ct).as_ambig_ct())
11201123
}
1121-
ast::GenericArg::Const(ct) => GenericArg::Const(self.lower_anon_const_to_const_arg(ct)),
11221124
}
11231125
}
11241126

@@ -1188,7 +1190,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
11881190

11891191
fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir> {
11901192
let kind = match &t.kind {
1191-
TyKind::Infer => hir::TyKind::Infer,
1193+
TyKind::Infer => hir::TyKind::Infer(()),
11921194
TyKind::Err(guar) => hir::TyKind::Err(*guar),
11931195
TyKind::Slice(ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx)),
11941196
TyKind::Ptr(mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)),
@@ -2044,7 +2046,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
20442046
)
20452047
.stash(c.value.span, StashKey::UnderscoreForArrayLengths);
20462048
}
2047-
let ct_kind = hir::ConstArgKind::Infer(self.lower_span(c.value.span));
2049+
let ct_kind = hir::ConstArgKind::Infer(self.lower_span(c.value.span), ());
20482050
self.arena.alloc(hir::ConstArg { hir_id: self.lower_node_id(c.id), kind: ct_kind })
20492051
}
20502052
_ => self.lower_anon_const_to_const_arg(c),

compiler/rustc_ast_lowering/src/path.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
525525
}
526526
FnRetTy::Default(_) => self.arena.alloc(self.ty_tup(*span, &[])),
527527
};
528-
let args = smallvec![GenericArg::Type(self.arena.alloc(self.ty_tup(*inputs_span, inputs)))];
528+
let args = smallvec![GenericArg::Type(
529+
self.arena.alloc(self.ty_tup(*inputs_span, inputs)).as_ambig_ty()
530+
)];
529531

530532
// If we have a bound like `async Fn() -> T`, make sure that we mark the
531533
// `Output = T` associated type bound with the right feature gates.

compiler/rustc_borrowck/src/diagnostics/region_errors.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_hir::QPath::Resolved;
88
use rustc_hir::WherePredicateKind::BoundPredicate;
99
use rustc_hir::def::Res::Def;
1010
use rustc_hir::def_id::DefId;
11-
use rustc_hir::intravisit::Visitor;
11+
use rustc_hir::intravisit::VisitorExt;
1212
use rustc_hir::{PolyTraitRef, TyKind, WhereBoundPredicate};
1313
use rustc_infer::infer::{NllRegionVariableOrigin, RelateParamBound};
1414
use rustc_middle::bug;
@@ -993,7 +993,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
993993
for found_did in found_dids {
994994
let mut traits = vec![];
995995
let mut hir_v = HirTraitObjectVisitor(&mut traits, *found_did);
996-
hir_v.visit_ty(self_ty);
996+
hir_v.visit_unambig_ty(self_ty);
997997
debug!("trait spans found: {:?}", traits);
998998
for span in &traits {
999999
let mut multi_span: MultiSpan = vec![*span].into();

compiler/rustc_borrowck/src/diagnostics/region_name.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
432432
// must highlight the variable.
433433
// NOTE(eddyb) this is handled in/by the sole caller
434434
// (`give_name_if_anonymous_region_appears_in_arguments`).
435-
hir::TyKind::Infer => None,
435+
hir::TyKind::Infer(()) => None,
436436

437437
_ => Some(argument_hir_ty),
438438
}
@@ -615,7 +615,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
615615
}
616616

617617
(GenericArgKind::Type(ty), hir::GenericArg::Type(hir_ty)) => {
618-
search_stack.push((ty, hir_ty));
618+
search_stack.push((ty, hir_ty.as_unambig_ty()));
619619
}
620620

621621
(GenericArgKind::Const(_ct), hir::GenericArg::Const(_hir_ct)) => {

compiler/rustc_hir/src/hir.rs

Lines changed: 74 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use crate::LangItem;
3131
use crate::def::{CtorKind, DefKind, Res};
3232
use crate::def_id::{DefId, LocalDefIdMap};
3333
pub(crate) use crate::hir_id::{HirId, ItemLocalId, ItemLocalMap, OwnerId};
34-
use crate::intravisit::FnKind;
34+
use crate::intravisit::{FnKind, VisitorExt};
3535

3636
#[derive(Debug, Copy, Clone, HashStable_Generic)]
3737
pub struct Lifetime {
@@ -263,10 +263,32 @@ impl<'hir> PathSegment<'hir> {
263263
/// that are [just paths](ConstArgKind::Path) (currently just bare const params)
264264
/// versus const args that are literals or have arbitrary computations (e.g., `{ 1 + 3 }`).
265265
#[derive(Clone, Copy, Debug, HashStable_Generic)]
266-
pub struct ConstArg<'hir> {
266+
#[repr(C)]
267+
pub struct ConstArg<'hir, Unambig = ()> {
267268
#[stable_hasher(ignore)]
268269
pub hir_id: HirId,
269-
pub kind: ConstArgKind<'hir>,
270+
pub kind: ConstArgKind<'hir, Unambig>,
271+
}
272+
273+
impl<'hir> ConstArg<'hir, AmbigArg> {
274+
pub fn as_unambig_ct(&self) -> &ConstArg<'hir> {
275+
// SAFETY: `ConstArg` is `repr(C)` and `ConstArgKind` is marked `repr(u8)` so that the
276+
// layout is the same across different ZST type arguments.
277+
let ptr = self as *const ConstArg<'hir, AmbigArg> as *const ConstArg<'hir, ()>;
278+
unsafe { &*ptr }
279+
}
280+
}
281+
282+
impl<'hir> ConstArg<'hir> {
283+
pub fn as_ambig_ct(&self) -> &ConstArg<'hir, AmbigArg> {
284+
assert!(!matches!(self.kind, ConstArgKind::Infer(_, ())));
285+
286+
// SAFETY: `ConstArg` is `repr(C)` and `ConstArgKind` is marked `repr(u8)` so that the layout is
287+
// the same across different ZST type arguments. We also asserted that the `self` is
288+
// not a `ConstArgKind::Infer` so there is no risk of transmuting a `()` to `AmbigArg`.
289+
let ptr = self as *const ConstArg<'hir> as *const ConstArg<'hir, AmbigArg>;
290+
unsafe { &*ptr }
291+
}
270292
}
271293

272294
impl<'hir> ConstArg<'hir> {
@@ -281,14 +303,15 @@ impl<'hir> ConstArg<'hir> {
281303
match self.kind {
282304
ConstArgKind::Path(path) => path.span(),
283305
ConstArgKind::Anon(anon) => anon.span,
284-
ConstArgKind::Infer(span) => span,
306+
ConstArgKind::Infer(span, _) => span,
285307
}
286308
}
287309
}
288310

289311
/// See [`ConstArg`].
290312
#[derive(Clone, Copy, Debug, HashStable_Generic)]
291-
pub enum ConstArgKind<'hir> {
313+
#[repr(u8, C)]
314+
pub enum ConstArgKind<'hir, Unambig = ()> {
292315
/// **Note:** Currently this is only used for bare const params
293316
/// (`N` where `fn foo<const N: usize>(...)`),
294317
/// not paths to any const (`N` where `const N: usize = ...`).
@@ -300,7 +323,7 @@ pub enum ConstArgKind<'hir> {
300323
/// `ConstArgKind::Infer`. In cases where it is ambiguous whether
301324
/// a generic arg is a type or a const, inference variables are
302325
/// represented as `GenericArg::Infer` instead.
303-
Infer(Span),
326+
Infer(Span, Unambig),
304327
}
305328

306329
#[derive(Clone, Copy, Debug, HashStable_Generic)]
@@ -311,15 +334,15 @@ pub struct InferArg {
311334

312335
impl InferArg {
313336
pub fn to_ty(&self) -> Ty<'static> {
314-
Ty { kind: TyKind::Infer, span: self.span, hir_id: self.hir_id }
337+
Ty { kind: TyKind::Infer(()), span: self.span, hir_id: self.hir_id }
315338
}
316339
}
317340

318341
#[derive(Debug, Clone, Copy, HashStable_Generic)]
319342
pub enum GenericArg<'hir> {
320343
Lifetime(&'hir Lifetime),
321-
Type(&'hir Ty<'hir>),
322-
Const(&'hir ConstArg<'hir>),
344+
Type(&'hir Ty<'hir, AmbigArg>),
345+
Const(&'hir ConstArg<'hir, AmbigArg>),
323346
/// **Note:** Inference variables are only represented as
324347
/// `GenericArg::Infer` in cases where it is ambiguous whether
325348
/// a generic arg is a type or a const. Otherwise, inference variables
@@ -332,7 +355,7 @@ impl GenericArg<'_> {
332355
match self {
333356
GenericArg::Lifetime(l) => l.ident.span,
334357
GenericArg::Type(t) => t.span,
335-
GenericArg::Const(c) => c.span(),
358+
GenericArg::Const(c) => c.as_unambig_ct().span(),
336359
GenericArg::Infer(i) => i.span,
337360
}
338361
}
@@ -351,7 +374,7 @@ impl GenericArg<'_> {
351374
GenericArg::Lifetime(_) => "lifetime",
352375
GenericArg::Type(_) => "type",
353376
GenericArg::Const(_) => "constant",
354-
GenericArg::Infer(_) => "inferred",
377+
GenericArg::Infer(_) => "placeholder",
355378
}
356379
}
357380

@@ -2869,10 +2892,35 @@ impl<'hir> AssocItemConstraintKind<'hir> {
28692892
}
28702893

28712894
#[derive(Debug, Clone, Copy, HashStable_Generic)]
2872-
pub struct Ty<'hir> {
2895+
pub enum AmbigArg {}
2896+
2897+
#[derive(Debug, Clone, Copy, HashStable_Generic)]
2898+
#[repr(C)]
2899+
pub struct Ty<'hir, Unambig = ()> {
28732900
pub hir_id: HirId,
2874-
pub kind: TyKind<'hir>,
28752901
pub span: Span,
2902+
pub kind: TyKind<'hir, Unambig>,
2903+
}
2904+
2905+
impl<'hir> Ty<'hir, AmbigArg> {
2906+
pub fn as_unambig_ty(&self) -> &Ty<'hir> {
2907+
// SAFETY: `Ty` is `repr(C)` and `TyKind` is marked `repr(u8)` so that the layout is
2908+
// the same across different ZST type arguments.
2909+
let ptr = self as *const Ty<'hir, AmbigArg> as *const Ty<'hir, ()>;
2910+
unsafe { &*ptr }
2911+
}
2912+
}
2913+
2914+
impl<'hir> Ty<'hir> {
2915+
pub fn as_ambig_ty(&self) -> &Ty<'hir, AmbigArg> {
2916+
assert!(!matches!(self.kind, TyKind::Infer(())));
2917+
2918+
// SAFETY: `Ty` is `repr(C)` and `TyKind` is marked `repr(u8)` so that the layout is
2919+
// the same across different ZST type arguments. We also asserted that the `self` is
2920+
// not a `TyKind::Infer` so there is no risk of transmuting a `()` to `AmbigArg`.
2921+
let ptr = self as *const Ty<'hir> as *const Ty<'hir, AmbigArg>;
2922+
unsafe { &*ptr }
2923+
}
28762924
}
28772925

28782926
impl<'hir> Ty<'hir> {
@@ -2904,7 +2952,7 @@ impl<'hir> Ty<'hir> {
29042952
use crate::intravisit::Visitor;
29052953
struct MyVisitor(Vec<Span>);
29062954
impl<'v> Visitor<'v> for MyVisitor {
2907-
fn visit_ty(&mut self, t: &'v Ty<'v>) {
2955+
fn visit_ty(&mut self, t: &'v Ty<'v, AmbigArg>) {
29082956
if matches!(
29092957
&t.kind,
29102958
TyKind::Path(QPath::Resolved(_, Path {
@@ -2915,12 +2963,12 @@ impl<'hir> Ty<'hir> {
29152963
self.0.push(t.span);
29162964
return;
29172965
}
2918-
crate::intravisit::walk_ty(self, t);
2966+
crate::intravisit::walk_ambig_ty(self, t);
29192967
}
29202968
}
29212969

29222970
let mut my_visitor = MyVisitor(vec![]);
2923-
my_visitor.visit_ty(self);
2971+
my_visitor.visit_unambig_ty(self);
29242972
my_visitor.0
29252973
}
29262974

@@ -2929,14 +2977,14 @@ impl<'hir> Ty<'hir> {
29292977
pub fn is_suggestable_infer_ty(&self) -> bool {
29302978
fn are_suggestable_generic_args(generic_args: &[GenericArg<'_>]) -> bool {
29312979
generic_args.iter().any(|arg| match arg {
2932-
GenericArg::Type(ty) => ty.is_suggestable_infer_ty(),
2980+
GenericArg::Type(ty) => ty.as_unambig_ty().is_suggestable_infer_ty(),
29332981
GenericArg::Infer(_) => true,
29342982
_ => false,
29352983
})
29362984
}
29372985
debug!(?self);
29382986
match &self.kind {
2939-
TyKind::Infer => true,
2987+
TyKind::Infer(()) => true,
29402988
TyKind::Slice(ty) => ty.is_suggestable_infer_ty(),
29412989
TyKind::Array(ty, length) => {
29422990
ty.is_suggestable_infer_ty() || matches!(length.kind, ConstArgKind::Infer(..))
@@ -3148,7 +3196,9 @@ pub enum InferDelegationKind {
31483196

31493197
/// The various kinds of types recognized by the compiler.
31503198
#[derive(Debug, Clone, Copy, HashStable_Generic)]
3151-
pub enum TyKind<'hir> {
3199+
// SAFETY: `repr(u8)` is required so that `TyKind<()>` and `TyKind<!>` are layout compatible
3200+
#[repr(u8, C)]
3201+
pub enum TyKind<'hir, Unambig = ()> {
31523202
/// Actual type should be inherited from `DefId` signature
31533203
InferDelegation(DefId, InferDelegationKind),
31543204
/// A variable length slice (i.e., `[T]`).
@@ -3184,18 +3234,18 @@ pub enum TyKind<'hir> {
31843234
),
31853235
/// Unused for now.
31863236
Typeof(&'hir AnonConst),
3237+
/// Placeholder for a type that has failed to be defined.
3238+
Err(rustc_span::ErrorGuaranteed),
3239+
/// Pattern types (`pattern_type!(u32 is 1..)`)
3240+
Pat(&'hir Ty<'hir>, &'hir Pat<'hir>),
31873241
/// `TyKind::Infer` means the type should be inferred instead of it having been
31883242
/// specified. This can appear anywhere in a type.
31893243
///
31903244
/// **Note:** Not all inferred types are represented as
31913245
/// `TyKind::Infer`. In cases where it is ambiguous whether
31923246
/// a generic arg is a type or a const, inference variables are
31933247
/// represented as `GenericArg::Infer` instead.
3194-
Infer,
3195-
/// Placeholder for a type that has failed to be defined.
3196-
Err(rustc_span::ErrorGuaranteed),
3197-
/// Pattern types (`pattern_type!(u32 is 1..)`)
3198-
Pat(&'hir Ty<'hir>, &'hir Pat<'hir>),
3248+
Infer(Unambig),
31993249
}
32003250

32013251
#[derive(Debug, Clone, Copy, HashStable_Generic)]

0 commit comments

Comments
 (0)