Skip to content

Commit 735e85c

Browse files
committed
add generics to hir::AnonConst
1 parent 3e6b19b commit 735e85c

File tree

18 files changed

+197
-48
lines changed

18 files changed

+197
-48
lines changed

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 62 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
512512
_ => visit::walk_ty(self, t),
513513
}
514514
}
515+
516+
fn visit_anon_const(&mut self, ct: &'tcx AnonConst) {
517+
self.lctx.allocate_hir_id_counter(ct.id);
518+
self.with_hir_id_owner(Some(ct.id), |this| {
519+
visit::walk_anon_const(this, ct);
520+
});
521+
}
515522
}
516523

517524
self.lower_node_id(CRATE_NODE_ID);
@@ -1158,9 +1165,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
11581165
tokens: None,
11591166
};
11601167

1161-
let ct = self.with_new_scopes(|this| hir::AnonConst {
1162-
hir_id: this.lower_node_id(node_id),
1163-
body: this.lower_const_body(path_expr.span, Some(&path_expr)),
1168+
let ct = self.lower_anon_const(&AnonConst {
1169+
id: node_id,
1170+
value: ast::ptr::P(path_expr),
11641171
});
11651172
return GenericArg::Const(ConstArg { value: ct, span: ty.span });
11661173
}
@@ -1169,7 +1176,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
11691176
GenericArg::Type(self.lower_ty_direct(&ty, itctx))
11701177
}
11711178
ast::GenericArg::Const(ct) => GenericArg::Const(ConstArg {
1172-
value: self.lower_anon_const(&ct),
1179+
value: self.lower_anon_const(ct),
11731180
span: ct.value.span,
11741181
}),
11751182
}
@@ -2320,10 +2327,57 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
23202327
self.expr_block(block, AttrVec::new())
23212328
}
23222329

2323-
fn lower_anon_const(&mut self, c: &AnonConst) -> hir::AnonConst {
2324-
self.with_new_scopes(|this| hir::AnonConst {
2325-
hir_id: this.lower_node_id(c.id),
2326-
body: this.lower_const_body(c.value.span, Some(&c.value)),
2330+
fn lower_anon_const(&mut self, c: &AnonConst) -> hir::AnonConst<'hir> {
2331+
self.with_new_scopes(|this| {
2332+
this.allocate_hir_id_counter(c.id);
2333+
this.with_hir_id_owner(c.id, |this| {
2334+
let def_id = this.resolver.local_def_id(c.id);
2335+
2336+
let hir_id = this.lower_node_id(c.id);
2337+
// Calculate all the lifetimes that should be captured
2338+
// by the opaque type. This should include all in-scope
2339+
// lifetime parameters, including those defined in-band.
2340+
//
2341+
// Note: this must be done after lowering the output type,
2342+
// as the output type may introduce new in-band lifetimes.
2343+
let lifetime_params: Vec<(Span, ParamName)> = this
2344+
.in_scope_lifetimes
2345+
.iter()
2346+
.cloned()
2347+
.map(|name| (name.ident().span, name))
2348+
.chain(this.lifetimes_to_define.iter().cloned())
2349+
.collect();
2350+
2351+
let generic_params =
2352+
this.arena.alloc_from_iter(lifetime_params.iter().map(|&(span, hir_name)| {
2353+
this.lifetime_to_generic_param(span, hir_name, def_id)
2354+
}));
2355+
2356+
let mut generic_args = Vec::with_capacity(lifetime_params.len());
2357+
generic_args.extend(lifetime_params.iter().map(|&(span, hir_name)| {
2358+
GenericArg::Lifetime(hir::Lifetime {
2359+
hir_id: this.next_id(),
2360+
span,
2361+
name: hir::LifetimeName::Param(hir_name),
2362+
})
2363+
}));
2364+
let generic_args = this.arena.alloc_from_iter(generic_args);
2365+
2366+
hir::AnonConst {
2367+
hir_id,
2368+
generics: hir::Generics {
2369+
params: generic_params,
2370+
where_clause: hir::WhereClause { predicates: &[], span: c.value.span },
2371+
span: c.value.span,
2372+
},
2373+
generic_args: hir::GenericArgs {
2374+
args: generic_args,
2375+
bindings: &[],
2376+
parenthesized: false,
2377+
},
2378+
body: this.lower_const_body(c.value.span, Some(&c.value)),
2379+
}
2380+
})
23272381
})
23282382
}
23292383

compiler/rustc_hir/src/hir.rs

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -241,17 +241,17 @@ impl<'hir> PathSegment<'hir> {
241241
}
242242
}
243243

244-
#[derive(Encodable, Debug, HashStable_Generic)]
245-
pub struct ConstArg {
246-
pub value: AnonConst,
244+
#[derive(Debug, HashStable_Generic)]
245+
pub struct ConstArg<'hir> {
246+
pub value: AnonConst<'hir>,
247247
pub span: Span,
248248
}
249249

250250
#[derive(Debug, HashStable_Generic)]
251251
pub enum GenericArg<'hir> {
252252
Lifetime(Lifetime),
253253
Type(Ty<'hir>),
254-
Const(ConstArg),
254+
Const(ConstArg<'hir>),
255255
}
256256

257257
impl GenericArg<'_> {
@@ -1354,9 +1354,11 @@ pub type Lit = Spanned<LitKind>;
13541354
/// These are usually found nested inside types (e.g., array lengths)
13551355
/// or expressions (e.g., repeat counts), and also used to define
13561356
/// explicit discriminant values for enum variants.
1357-
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Debug, HashStable_Generic)]
1358-
pub struct AnonConst {
1357+
#[derive(Debug, HashStable_Generic)]
1358+
pub struct AnonConst<'hir> {
13591359
pub hir_id: HirId,
1360+
pub generics: Generics<'hir>,
1361+
pub generic_args: GenericArgs<'hir>,
13601362
pub body: BodyId,
13611363
}
13621364

@@ -1371,7 +1373,7 @@ pub struct Expr<'hir> {
13711373

13721374
// `Expr` is used a lot. Make sure it doesn't unintentionally get bigger.
13731375
#[cfg(target_arch = "x86_64")]
1374-
rustc_data_structures::static_assert_size!(Expr<'static>, 72);
1376+
rustc_data_structures::static_assert_size!(Expr<'static>, 144);
13751377

13761378
impl Expr<'_> {
13771379
pub fn precedence(&self) -> ExprPrecedence {
@@ -1519,7 +1521,7 @@ pub enum ExprKind<'hir> {
15191521
/// A `box x` expression.
15201522
Box(&'hir Expr<'hir>),
15211523
/// Allow anonymous constants from an inline `const` block
1522-
ConstBlock(AnonConst),
1524+
ConstBlock(AnonConst<'hir>),
15231525
/// An array (e.g., `[a, b, c, d]`).
15241526
Array(&'hir [Expr<'hir>]),
15251527
/// A function call.
@@ -1619,7 +1621,7 @@ pub enum ExprKind<'hir> {
16191621
///
16201622
/// E.g., `[1; 5]`. The first expression is the element
16211623
/// to be repeated; the second is the number of times to repeat it.
1622-
Repeat(&'hir Expr<'hir>, AnonConst),
1624+
Repeat(&'hir Expr<'hir>, AnonConst<'hir>),
16231625

16241626
/// A suspension point for generators (i.e., `yield <expr>`).
16251627
Yield(&'hir Expr<'hir>, YieldSource),
@@ -2064,7 +2066,7 @@ pub enum TyKind<'hir> {
20642066
/// A variable length slice (i.e., `[T]`).
20652067
Slice(&'hir Ty<'hir>),
20662068
/// A fixed length array (i.e., `[T; n]`).
2067-
Array(&'hir Ty<'hir>, AnonConst),
2069+
Array(&'hir Ty<'hir>, AnonConst<'hir>),
20682070
/// A raw pointer (i.e., `*const T` or `*mut T`).
20692071
Ptr(MutTy<'hir>),
20702072
/// A reference (i.e., `&'a T` or `&'a mut T`).
@@ -2090,7 +2092,7 @@ pub enum TyKind<'hir> {
20902092
/// where `Bound` is a trait or a lifetime.
20912093
TraitObject(&'hir [PolyTraitRef<'hir>], Lifetime),
20922094
/// Unused for now.
2093-
Typeof(AnonConst),
2095+
Typeof(AnonConst<'hir>),
20942096
/// `TyKind::Infer` means the type should be inferred instead of it having been
20952097
/// specified. This can appear anywhere in a type.
20962098
Infer,
@@ -2306,7 +2308,7 @@ pub struct Variant<'hir> {
23062308
/// Fields and constructor id of the variant.
23072309
pub data: VariantData<'hir>,
23082310
/// Explicit discriminant (e.g., `Foo = 1`).
2309-
pub disr_expr: Option<AnonConst>,
2311+
pub disr_expr: Option<AnonConst<'hir>>,
23102312
/// Span
23112313
pub span: Span,
23122314
}
@@ -2693,7 +2695,7 @@ pub enum Node<'hir> {
26932695
ImplItem(&'hir ImplItem<'hir>),
26942696
Variant(&'hir Variant<'hir>),
26952697
Field(&'hir StructField<'hir>),
2696-
AnonConst(&'hir AnonConst),
2698+
AnonConst(&'hir AnonConst<'hir>),
26972699
Expr(&'hir Expr<'hir>),
26982700
Stmt(&'hir Stmt<'hir>),
26992701
PathSegment(&'hir PathSegment<'hir>),

compiler/rustc_hir/src/intravisit.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ pub trait Visitor<'v>: Sized {
362362
fn visit_pat(&mut self, p: &'v Pat<'v>) {
363363
walk_pat(self, p)
364364
}
365-
fn visit_anon_const(&mut self, c: &'v AnonConst) {
365+
fn visit_anon_const(&mut self, c: &'v AnonConst<'v>) {
366366
walk_anon_const(self, c)
367367
}
368368
fn visit_expr(&mut self, ex: &'v Expr<'v>) {
@@ -1089,7 +1089,7 @@ pub fn walk_stmt<'v, V: Visitor<'v>>(visitor: &mut V, statement: &'v Stmt<'v>) {
10891089
}
10901090
}
10911091

1092-
pub fn walk_anon_const<'v, V: Visitor<'v>>(visitor: &mut V, constant: &'v AnonConst) {
1092+
pub fn walk_anon_const<'v, V: Visitor<'v>>(visitor: &mut V, constant: &'v AnonConst<'v>) {
10931093
visitor.visit_id(constant.hir_id);
10941094
visitor.visit_nested_body(constant.body);
10951095
}

compiler/rustc_hir_pretty/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1083,7 +1083,7 @@ impl<'a> State<'a> {
10831083
self.ann.post(self, AnnNode::Block(blk))
10841084
}
10851085

1086-
pub fn print_anon_const(&mut self, constant: &hir::AnonConst) {
1086+
pub fn print_anon_const(&mut self, constant: &hir::AnonConst<'_>) {
10871087
self.ann.nested(self, Nested::Body(constant.body))
10881088
}
10891089

@@ -1132,14 +1132,14 @@ impl<'a> State<'a> {
11321132
self.end()
11331133
}
11341134

1135-
fn print_expr_anon_const(&mut self, anon_const: &hir::AnonConst) {
1135+
fn print_expr_anon_const(&mut self, anon_const: &hir::AnonConst<'_>) {
11361136
self.ibox(INDENT_UNIT);
11371137
self.s.word_space("const");
11381138
self.print_anon_const(anon_const);
11391139
self.end()
11401140
}
11411141

1142-
fn print_expr_repeat(&mut self, element: &hir::Expr<'_>, count: &hir::AnonConst) {
1142+
fn print_expr_repeat(&mut self, element: &hir::Expr<'_>, count: &hir::AnonConst<'_>) {
11431143
self.ibox(INDENT_UNIT);
11441144
self.s.word("[");
11451145
self.print_expr(element);

compiler/rustc_metadata/src/rmeta/encoder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1780,7 +1780,7 @@ impl Visitor<'tcx> for EncodeContext<'a, 'tcx> {
17801780
intravisit::walk_expr(self, ex);
17811781
self.encode_info_for_expr(ex);
17821782
}
1783-
fn visit_anon_const(&mut self, c: &'tcx AnonConst) {
1783+
fn visit_anon_const(&mut self, c: &'tcx AnonConst<'_>) {
17841784
intravisit::walk_anon_const(self, c);
17851785
let def_id = self.tcx.hir().local_def_id(c.hir_id);
17861786
self.encode_info_for_anon_const(def_id);

compiler/rustc_middle/src/hir/map/collector.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -441,11 +441,17 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
441441
});
442442
}
443443

444-
fn visit_anon_const(&mut self, constant: &'hir AnonConst) {
445-
self.insert(DUMMY_SP, constant.hir_id, Node::AnonConst(constant));
444+
fn visit_anon_const(&mut self, constant: &'hir AnonConst<'hir>) {
445+
debug_assert_eq!(
446+
constant.hir_id.owner,
447+
self.definitions.opt_hir_id_to_local_def_id(constant.hir_id).unwrap()
448+
);
449+
self.with_dep_node_owner(constant.hir_id.owner, constant, |this, hash| {
450+
this.insert_with_hash(DUMMY_SP, constant.hir_id, Node::AnonConst(constant), hash);
446451

447-
self.with_parent(constant.hir_id, |this| {
448-
intravisit::walk_anon_const(this, constant);
452+
this.with_parent(constant.hir_id, |this| {
453+
intravisit::walk_anon_const(this, constant);
454+
})
449455
});
450456
}
451457

compiler/rustc_middle/src/ty/consts.rs

Lines changed: 77 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use crate::mir::interpret::{LitToConstInput, Scalar};
33
use crate::ty::subst::InternalSubsts;
44
use crate::ty::{self, Ty, TyCtxt};
55
use crate::ty::{ParamEnv, ParamEnvAnd};
6+
use crate::middle::resolve_lifetime as rl;
67
use rustc_errors::ErrorReported;
78
use rustc_hir as hir;
89
use rustc_hir::def_id::LocalDefId;
@@ -41,15 +42,17 @@ impl<'tcx> Const<'tcx> {
4142

4243
let hir_id = tcx.hir().local_def_id_to_hir_id(def.did);
4344

44-
let body_id = match tcx.hir().get(hir_id) {
45-
hir::Node::AnonConst(ac) => ac.body,
45+
let hir_ct = match tcx.hir().get(hir_id) {
46+
hir::Node::AnonConst(ac) => ac,
4647
_ => span_bug!(
4748
tcx.def_span(def.did.to_def_id()),
4849
"from_anon_const can only process anonymous constants"
4950
),
5051
};
5152

52-
let expr = &tcx.hir().body(body_id).value;
53+
warn!(?hir_ct.generics, ?hir_ct.generic_args);
54+
55+
let expr = &tcx.hir().body(hir_ct.body).value;
5356

5457
let ty = tcx.type_of(def.def_id_for_type_of());
5558

@@ -97,11 +100,77 @@ impl<'tcx> Const<'tcx> {
97100
let name = tcx.hir().name(hir_id);
98101
ty::ConstKind::Param(ty::ParamConst::new(index, name))
99102
}
100-
_ => ty::ConstKind::Unevaluated(
101-
def.to_global(),
102-
InternalSubsts::identity_for_item(tcx, def.did.to_def_id()),
103-
None,
104-
),
103+
_ => {
104+
let generics = tcx.generics_of(def.did);
105+
let substs = InternalSubsts::for_item(tcx, def.did.to_def_id(), |param, _| {
106+
if let Some(i) =
107+
(param.index as usize).checked_sub(generics.parent_count)
108+
{
109+
// Our own parameters are the resolved lifetimes.
110+
match param.kind {
111+
ty::GenericParamDefKind::Lifetime => {
112+
if let hir::GenericArg::Lifetime(lifetime) = &hir_ct.generic_args.args[i] {
113+
let lifetime_name = |def_id| {
114+
tcx.hir().name(tcx.hir().local_def_id_to_hir_id(def_id))
115+
};
116+
117+
match tcx.named_region(lifetime.hir_id) {
118+
Some(rl::Region::Static) => tcx.lifetimes.re_static,
119+
120+
Some(rl::Region::LateBound(debruijn, id, _)) => {
121+
let name = lifetime_name(id.expect_local());
122+
tcx.mk_region(ty::ReLateBound(
123+
debruijn,
124+
ty::BrNamed(id, name),
125+
))
126+
}
127+
128+
Some(rl::Region::LateBoundAnon(debruijn, index)) => tcx
129+
.mk_region(ty::ReLateBound(
130+
debruijn,
131+
ty::BrAnon(index),
132+
)),
133+
134+
Some(rl::Region::EarlyBound(index, id, _)) => {
135+
let name = lifetime_name(id.expect_local());
136+
tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion {
137+
def_id: id,
138+
index,
139+
name,
140+
}))
141+
}
142+
143+
Some(rl::Region::Free(scope, id)) => {
144+
let name = lifetime_name(id.expect_local());
145+
tcx.mk_region(ty::ReFree(ty::FreeRegion {
146+
scope,
147+
bound_region: ty::BrNamed(id, name),
148+
}))
149+
150+
// (*) -- not late-bound, won't change
151+
}
152+
153+
None => {
154+
tcx.sess.delay_span_bug(
155+
lifetime.span,
156+
"unelided lifetime in signature",
157+
);
158+
tcx.lifetimes.re_static
159+
}
160+
}
161+
} else {
162+
bug!()
163+
}
164+
}.into(),
165+
_ => bug!(),
166+
}
167+
} else {
168+
tcx.mk_param_from_def(param)
169+
}
170+
});
171+
172+
ty::ConstKind::Unevaluated(def.to_global(), substs, None)
173+
}
105174
};
106175

107176
tcx.mk_const(ty::Const { val, ty })

compiler/rustc_passes/src/check_const.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ impl<'tcx> Visitor<'tcx> for CheckConstVisitor<'tcx> {
183183
NestedVisitorMap::OnlyBodies(self.tcx.hir())
184184
}
185185

186-
fn visit_anon_const(&mut self, anon: &'tcx hir::AnonConst) {
186+
fn visit_anon_const(&mut self, anon: &'tcx hir::AnonConst<'_>) {
187187
let kind = Some(hir::ConstContext::Const);
188188
self.recurse_into(kind, None, |this| intravisit::walk_anon_const(this, anon));
189189
}

0 commit comments

Comments
 (0)