Skip to content

Commit 3fdbfb1

Browse files
committed
Split hir TyKind and ConstArgKind in two and update hir::Visitor
1 parent a8d3efc commit 3fdbfb1

File tree

50 files changed

+498
-343
lines changed

Some content is hidden

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

50 files changed

+498
-343
lines changed

compiler/rustc_ast_lowering/src/index.rs

Lines changed: 26 additions & 14 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};
@@ -258,14 +259,6 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
258259
});
259260
}
260261

261-
fn visit_const_arg(&mut self, const_arg: &'hir ConstArg<'hir>) {
262-
self.insert(const_arg.span(), const_arg.hir_id, Node::ConstArg(const_arg));
263-
264-
self.with_parent(const_arg.hir_id, |this| {
265-
intravisit::walk_const_arg(this, const_arg);
266-
});
267-
}
268-
269262
fn visit_expr(&mut self, expr: &'hir Expr<'hir>) {
270263
self.insert(expr.span, expr.hir_id, Node::Expr(expr));
271264

@@ -295,22 +288,41 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
295288
intravisit::walk_path_segment(self, path_segment);
296289
}
297290

298-
fn visit_ty(&mut self, ty: &'hir Ty<'hir>) {
299-
self.insert(ty.span, ty.hir_id, Node::Ty(ty));
291+
fn visit_ty(&mut self, ty: &'hir Ty<'hir, AmbigArg>) {
292+
self.insert(ty.span, ty.hir_id, Node::Ty(ty.as_unambig_ty()));
300293

301294
self.with_parent(ty.hir_id, |this| {
302295
intravisit::walk_ty(this, ty);
303296
});
304297
}
305298

306-
fn visit_infer(&mut self, inf: &'hir InferArg) {
307-
self.insert(inf.span, inf.hir_id, Node::Infer(inf));
299+
fn visit_const_arg(&mut self, const_arg: &'hir ConstArg<'hir, AmbigArg>) {
300+
self.insert(
301+
const_arg.as_unambig_ct().span(),
302+
const_arg.hir_id,
303+
Node::ConstArg(const_arg.as_unambig_ct()),
304+
);
308305

309-
self.with_parent(inf.hir_id, |this| {
310-
intravisit::walk_inf(this, inf);
306+
self.with_parent(const_arg.hir_id, |this| {
307+
intravisit::walk_ambig_const_arg(this, const_arg);
311308
});
312309
}
313310

311+
fn visit_infer(
312+
&mut self,
313+
inf_id: HirId,
314+
inf_span: Span,
315+
kind: InferKind<'hir>,
316+
) -> Self::Result {
317+
match kind {
318+
InferKind::Ty(ty) => self.insert(inf_span, inf_id, Node::Ty(ty)),
319+
InferKind::Const(ct) => self.insert(inf_span, inf_id, Node::ConstArg(ct)),
320+
InferKind::Ambig(inf) => self.insert(inf_span, inf_id, Node::Infer(inf)),
321+
}
322+
323+
self.visit_id(inf_id);
324+
}
325+
314326
fn visit_trait_ref(&mut self, tr: &'hir TraitRef<'hir>) {
315327
self.insert(tr.path.span, tr.hir_ref_id, Node::TraitRef(tr));
316328

compiler/rustc_ast_lowering/src/lib.rs

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

11121112
let ct =
11131113
self.lower_const_path_to_const_arg(path, res, ty.id, ty.span);
1114-
return GenericArg::Const(ct);
1114+
return GenericArg::Const(ct.try_as_ambig_ct().unwrap());
11151115
}
11161116
}
11171117
}
11181118
_ => {}
11191119
}
1120-
GenericArg::Type(self.lower_ty(ty, itctx))
1120+
GenericArg::Type(self.lower_ty(ty, itctx).try_as_ambig_ty().unwrap())
1121+
}
1122+
ast::GenericArg::Const(ct) => {
1123+
GenericArg::Const(self.lower_anon_const_to_const_arg(ct).try_as_ambig_ct().unwrap())
11211124
}
1122-
ast::GenericArg::Const(ct) => GenericArg::Const(self.lower_anon_const_to_const_arg(ct)),
11231125
}
11241126
}
11251127

@@ -1189,7 +1191,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
11891191

11901192
fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir> {
11911193
let kind = match &t.kind {
1192-
TyKind::Infer => hir::TyKind::Infer,
1194+
TyKind::Infer => hir::TyKind::Infer(()),
11931195
TyKind::Err(guar) => hir::TyKind::Err(*guar),
11941196
TyKind::Slice(ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx)),
11951197
TyKind::Ptr(mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)),
@@ -2045,7 +2047,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
20452047
)
20462048
.stash(c.value.span, StashKey::UnderscoreForArrayLengths);
20472049
}
2048-
let ct_kind = hir::ConstArgKind::Infer(self.lower_span(c.value.span));
2050+
let ct_kind = hir::ConstArgKind::Infer(self.lower_span(c.value.span), ());
20492051
self.arena.alloc(hir::ConstArg { hir_id: self.lower_node_id(c.id), kind: ct_kind })
20502052
}
20512053
_ => 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)).try_as_ambig_ty().unwrap()
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;
@@ -987,7 +987,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
987987
for found_did in found_dids {
988988
let mut traits = vec![];
989989
let mut hir_v = HirTraitObjectVisitor(&mut traits, *found_did);
990-
hir_v.visit_ty(self_ty);
990+
hir_v.visit_unambig_ty(self_ty);
991991
debug!("trait spans found: {:?}", traits);
992992
for span in &traits {
993993
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: 77 additions & 23 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,34 @@ 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 try_as_ambig_ct(&self) -> Option<&ConstArg<'hir, AmbigArg>> {
284+
if let ConstArgKind::Infer(_, ()) = self.kind {
285+
return None;
286+
}
287+
288+
// SAFETY: `ConstArg` is `repr(C)` and `ConstArgKind` is marked `repr(u8)` so that the layout is
289+
// the same across different ZST type arguments. We also asserted that the `self` is
290+
// not a `ConstArgKind::Infer` so there is no risk of transmuting a `()` to `AmbigArg`.
291+
let ptr = self as *const ConstArg<'hir> as *const ConstArg<'hir, AmbigArg>;
292+
Some(unsafe { &*ptr })
293+
}
270294
}
271295

272296
impl<'hir> ConstArg<'hir> {
@@ -281,14 +305,15 @@ impl<'hir> ConstArg<'hir> {
281305
match self.kind {
282306
ConstArgKind::Path(path) => path.span(),
283307
ConstArgKind::Anon(anon) => anon.span,
284-
ConstArgKind::Infer(span) => span,
308+
ConstArgKind::Infer(span, _) => span,
285309
}
286310
}
287311
}
288312

289313
/// See [`ConstArg`].
290314
#[derive(Clone, Copy, Debug, HashStable_Generic)]
291-
pub enum ConstArgKind<'hir> {
315+
#[repr(u8, C)]
316+
pub enum ConstArgKind<'hir, Unambig = ()> {
292317
/// **Note:** Currently this is only used for bare const params
293318
/// (`N` where `fn foo<const N: usize>(...)`),
294319
/// not paths to any const (`N` where `const N: usize = ...`).
@@ -300,7 +325,7 @@ pub enum ConstArgKind<'hir> {
300325
/// `ConstArgKind::Infer`. In cases where it is ambiguous whether
301326
/// a generic arg is a type or a const, inference variables are
302327
/// represented as `GenericArg::Infer` instead.
303-
Infer(Span),
328+
Infer(Span, Unambig),
304329
}
305330

306331
#[derive(Clone, Copy, Debug, HashStable_Generic)]
@@ -311,15 +336,15 @@ pub struct InferArg {
311336

312337
impl InferArg {
313338
pub fn to_ty(&self) -> Ty<'static> {
314-
Ty { kind: TyKind::Infer, span: self.span, hir_id: self.hir_id }
339+
Ty { kind: TyKind::Infer(()), span: self.span, hir_id: self.hir_id }
315340
}
316341
}
317342

318343
#[derive(Debug, Clone, Copy, HashStable_Generic)]
319344
pub enum GenericArg<'hir> {
320345
Lifetime(&'hir Lifetime),
321-
Type(&'hir Ty<'hir>),
322-
Const(&'hir ConstArg<'hir>),
346+
Type(&'hir Ty<'hir, AmbigArg>),
347+
Const(&'hir ConstArg<'hir, AmbigArg>),
323348
/// **Note:** Inference variables are only represented as
324349
/// `GenericArg::Infer` in cases where it is ambiguous whether
325350
/// a generic arg is a type or a const. Otherwise, inference variables
@@ -332,7 +357,7 @@ impl GenericArg<'_> {
332357
match self {
333358
GenericArg::Lifetime(l) => l.ident.span,
334359
GenericArg::Type(t) => t.span,
335-
GenericArg::Const(c) => c.span(),
360+
GenericArg::Const(c) => c.as_unambig_ct().span(),
336361
GenericArg::Infer(i) => i.span,
337362
}
338363
}
@@ -351,7 +376,7 @@ impl GenericArg<'_> {
351376
GenericArg::Lifetime(_) => "lifetime",
352377
GenericArg::Type(_) => "type",
353378
GenericArg::Const(_) => "constant",
354-
GenericArg::Infer(_) => "inferred",
379+
GenericArg::Infer(_) => "placeholder",
355380
}
356381
}
357382

@@ -2904,10 +2929,37 @@ impl<'hir> AssocItemConstraintKind<'hir> {
29042929
}
29052930

29062931
#[derive(Debug, Clone, Copy, HashStable_Generic)]
2907-
pub struct Ty<'hir> {
2932+
pub enum AmbigArg {}
2933+
2934+
#[derive(Debug, Clone, Copy, HashStable_Generic)]
2935+
#[repr(C)]
2936+
pub struct Ty<'hir, Unambig = ()> {
29082937
pub hir_id: HirId,
2909-
pub kind: TyKind<'hir>,
29102938
pub span: Span,
2939+
pub kind: TyKind<'hir, Unambig>,
2940+
}
2941+
2942+
impl<'hir> Ty<'hir, AmbigArg> {
2943+
pub fn as_unambig_ty(&self) -> &Ty<'hir> {
2944+
// SAFETY: `Ty` is `repr(C)` and `TyKind` is marked `repr(u8)` so that the layout is
2945+
// the same across different ZST type arguments.
2946+
let ptr = self as *const Ty<'hir, AmbigArg> as *const Ty<'hir, ()>;
2947+
unsafe { &*ptr }
2948+
}
2949+
}
2950+
2951+
impl<'hir> Ty<'hir> {
2952+
pub fn try_as_ambig_ty(&self) -> Option<&Ty<'hir, AmbigArg>> {
2953+
if let TyKind::Infer(()) = self.kind {
2954+
return None;
2955+
}
2956+
2957+
// SAFETY: `Ty` is `repr(C)` and `TyKind` is marked `repr(u8)` so that the layout is
2958+
// the same across different ZST type arguments. We also asserted that the `self` is
2959+
// not a `TyKind::Infer` so there is no risk of transmuting a `()` to `AmbigArg`.
2960+
let ptr = self as *const Ty<'hir> as *const Ty<'hir, AmbigArg>;
2961+
Some(unsafe { &*ptr })
2962+
}
29112963
}
29122964

29132965
impl<'hir> Ty<'hir> {
@@ -2939,7 +2991,7 @@ impl<'hir> Ty<'hir> {
29392991
use crate::intravisit::Visitor;
29402992
struct MyVisitor(Vec<Span>);
29412993
impl<'v> Visitor<'v> for MyVisitor {
2942-
fn visit_ty(&mut self, t: &'v Ty<'v>) {
2994+
fn visit_ty(&mut self, t: &'v Ty<'v, AmbigArg>) {
29432995
if matches!(
29442996
&t.kind,
29452997
TyKind::Path(QPath::Resolved(_, Path {
@@ -2955,7 +3007,7 @@ impl<'hir> Ty<'hir> {
29553007
}
29563008

29573009
let mut my_visitor = MyVisitor(vec![]);
2958-
my_visitor.visit_ty(self);
3010+
my_visitor.visit_unambig_ty(self);
29593011
my_visitor.0
29603012
}
29613013

@@ -2964,14 +3016,14 @@ impl<'hir> Ty<'hir> {
29643016
pub fn is_suggestable_infer_ty(&self) -> bool {
29653017
fn are_suggestable_generic_args(generic_args: &[GenericArg<'_>]) -> bool {
29663018
generic_args.iter().any(|arg| match arg {
2967-
GenericArg::Type(ty) => ty.is_suggestable_infer_ty(),
3019+
GenericArg::Type(ty) => ty.as_unambig_ty().is_suggestable_infer_ty(),
29683020
GenericArg::Infer(_) => true,
29693021
_ => false,
29703022
})
29713023
}
29723024
debug!(?self);
29733025
match &self.kind {
2974-
TyKind::Infer => true,
3026+
TyKind::Infer(()) => true,
29753027
TyKind::Slice(ty) => ty.is_suggestable_infer_ty(),
29763028
TyKind::Array(ty, length) => {
29773029
ty.is_suggestable_infer_ty() || matches!(length.kind, ConstArgKind::Infer(..))
@@ -3183,7 +3235,9 @@ pub enum InferDelegationKind {
31833235

31843236
/// The various kinds of types recognized by the compiler.
31853237
#[derive(Debug, Clone, Copy, HashStable_Generic)]
3186-
pub enum TyKind<'hir> {
3238+
// SAFETY: `repr(u8)` is required so that `TyKind<()>` and `TyKind<!>` are layout compatible
3239+
#[repr(u8, C)]
3240+
pub enum TyKind<'hir, Unambig = ()> {
31873241
/// Actual type should be inherited from `DefId` signature
31883242
InferDelegation(DefId, InferDelegationKind),
31893243
/// A variable length slice (i.e., `[T]`).
@@ -3216,18 +3270,18 @@ pub enum TyKind<'hir> {
32163270
TraitObject(&'hir [PolyTraitRef<'hir>], TaggedRef<'hir, Lifetime, TraitObjectSyntax>),
32173271
/// Unused for now.
32183272
Typeof(&'hir AnonConst),
3273+
/// Placeholder for a type that has failed to be defined.
3274+
Err(rustc_span::ErrorGuaranteed),
3275+
/// Pattern types (`pattern_type!(u32 is 1..)`)
3276+
Pat(&'hir Ty<'hir>, &'hir Pat<'hir>),
32193277
/// `TyKind::Infer` means the type should be inferred instead of it having been
32203278
/// specified. This can appear anywhere in a type.
32213279
///
32223280
/// **Note:** Not all inferred types are represented as
32233281
/// `TyKind::Infer`. In cases where it is ambiguous whether
32243282
/// a generic arg is a type or a const, inference variables are
32253283
/// represented as `GenericArg::Infer` instead.
3226-
Infer,
3227-
/// Placeholder for a type that has failed to be defined.
3228-
Err(rustc_span::ErrorGuaranteed),
3229-
/// Pattern types (`pattern_type!(u32 is 1..)`)
3230-
Pat(&'hir Ty<'hir>, &'hir Pat<'hir>),
3284+
Infer(Unambig),
32313285
}
32323286

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

0 commit comments

Comments
 (0)