Skip to content

Commit f3e9763

Browse files
committed
ast: make = <expr>; optional in free statics/consts.
1 parent 95dc9b9 commit f3e9763

File tree

19 files changed

+250
-132
lines changed

19 files changed

+250
-132
lines changed

src/librustc_ast_lowering/item.rs

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -269,26 +269,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
269269
self.lower_use_tree(use_tree, &prefix, id, vis, ident, attrs)
270270
}
271271
ItemKind::Static(ref t, m, ref e) => {
272-
let ty = self.lower_ty(
273-
t,
274-
if self.sess.features_untracked().impl_trait_in_bindings {
275-
ImplTraitContext::OpaqueTy(None, hir::OpaqueTyOrigin::Misc)
276-
} else {
277-
ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
278-
},
279-
);
280-
hir::ItemKind::Static(ty, m, self.lower_const_body(span, Some(e)))
272+
let (ty, body_id) = self.lower_const_item(t, span, e.as_deref());
273+
hir::ItemKind::Static(ty, m, body_id)
281274
}
282275
ItemKind::Const(ref t, ref e) => {
283-
let ty = self.lower_ty(
284-
t,
285-
if self.sess.features_untracked().impl_trait_in_bindings {
286-
ImplTraitContext::OpaqueTy(None, hir::OpaqueTyOrigin::Misc)
287-
} else {
288-
ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
289-
},
290-
);
291-
hir::ItemKind::Const(ty, self.lower_const_body(span, Some(e)))
276+
let (ty, body_id) = self.lower_const_item(t, span, e.as_deref());
277+
hir::ItemKind::Const(ty, body_id)
292278
}
293279
ItemKind::Fn(FnSig { ref decl, header }, ref generics, ref body) => {
294280
let fn_def_id = self.resolver.definitions().local_def_id(id);
@@ -457,6 +443,21 @@ impl<'hir> LoweringContext<'_, 'hir> {
457443
// not cause an assertion failure inside the `lower_defaultness` function.
458444
}
459445

446+
fn lower_const_item(
447+
&mut self,
448+
ty: &Ty,
449+
span: Span,
450+
body: Option<&Expr>,
451+
) -> (&'hir hir::Ty<'hir>, hir::BodyId) {
452+
let itctx = if self.sess.features_untracked().impl_trait_in_bindings {
453+
ImplTraitContext::OpaqueTy(None, hir::OpaqueTyOrigin::Misc)
454+
} else {
455+
ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
456+
};
457+
let ty = self.lower_ty(ty, itctx);
458+
(ty, self.lower_const_body(span, body))
459+
}
460+
460461
fn lower_use_tree(
461462
&mut self,
462463
tree: &UseTree,

src/librustc_ast_passes/ast_validation.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -948,6 +948,14 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
948948
self.err_handler().span_err(item.span, "unions cannot have zero fields");
949949
}
950950
}
951+
ItemKind::Const(.., None) => {
952+
let msg = "free constant item without body";
953+
self.error_item_without_body(item.span, "constant", msg, " = <expr>;");
954+
}
955+
ItemKind::Static(.., None) => {
956+
let msg = "free static item without body";
957+
self.error_item_without_body(item.span, "static", msg, " = <expr>;");
958+
}
951959
_ => {}
952960
}
953961

src/librustc_ast_pretty/pprust.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1124,9 +1124,10 @@ impl<'a> State<'a> {
11241124
self.print_type(ty);
11251125
self.s.space();
11261126
self.end(); // end the head-ibox
1127-
1128-
self.word_space("=");
1129-
self.print_expr(expr);
1127+
if let Some(expr) = expr {
1128+
self.word_space("=");
1129+
self.print_expr(expr);
1130+
}
11301131
self.s.word(";");
11311132
self.end(); // end the outer cbox
11321133
}
@@ -1137,9 +1138,10 @@ impl<'a> State<'a> {
11371138
self.print_type(ty);
11381139
self.s.space();
11391140
self.end(); // end the head-ibox
1140-
1141-
self.word_space("=");
1142-
self.print_expr(expr);
1141+
if let Some(expr) = expr {
1142+
self.word_space("=");
1143+
self.print_expr(expr);
1144+
}
11431145
self.s.word(";");
11441146
self.end(); // end the outer cbox
11451147
}

src/librustc_builtin_macros/test.rs

Lines changed: 76 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -186,81 +186,85 @@ pub fn expand_test_or_bench(
186186
ast::ItemKind::Const(
187187
cx.ty(sp, ast::TyKind::Path(None, test_path("TestDescAndFn"))),
188188
// test::TestDescAndFn {
189-
cx.expr_struct(
190-
sp,
191-
test_path("TestDescAndFn"),
192-
vec![
193-
// desc: test::TestDesc {
194-
field(
195-
"desc",
196-
cx.expr_struct(
197-
sp,
198-
test_path("TestDesc"),
199-
vec![
200-
// name: "path::to::test"
201-
field(
202-
"name",
203-
cx.expr_call(
204-
sp,
205-
cx.expr_path(test_path("StaticTestName")),
206-
vec![cx.expr_str(
207-
sp,
208-
Symbol::intern(&item_path(
209-
// skip the name of the root module
210-
&cx.current_expansion.module.mod_path[1..],
211-
&item.ident,
212-
)),
213-
)],
214-
),
215-
),
216-
// ignore: true | false
217-
field("ignore", cx.expr_bool(sp, should_ignore(&item))),
218-
// allow_fail: true | false
219-
field("allow_fail", cx.expr_bool(sp, should_fail(&item))),
220-
// should_panic: ...
221-
field(
222-
"should_panic",
223-
match should_panic(cx, &item) {
224-
// test::ShouldPanic::No
225-
ShouldPanic::No => cx.expr_path(should_panic_path("No")),
226-
// test::ShouldPanic::Yes
227-
ShouldPanic::Yes(None) => {
228-
cx.expr_path(should_panic_path("Yes"))
229-
}
230-
// test::ShouldPanic::YesWithMessage("...")
231-
ShouldPanic::Yes(Some(sym)) => cx.expr_call(
189+
Some(
190+
cx.expr_struct(
191+
sp,
192+
test_path("TestDescAndFn"),
193+
vec![
194+
// desc: test::TestDesc {
195+
field(
196+
"desc",
197+
cx.expr_struct(
198+
sp,
199+
test_path("TestDesc"),
200+
vec![
201+
// name: "path::to::test"
202+
field(
203+
"name",
204+
cx.expr_call(
232205
sp,
233-
cx.expr_path(should_panic_path("YesWithMessage")),
234-
vec![cx.expr_str(sp, sym)],
206+
cx.expr_path(test_path("StaticTestName")),
207+
vec![cx.expr_str(
208+
sp,
209+
Symbol::intern(&item_path(
210+
// skip the name of the root module
211+
&cx.current_expansion.module.mod_path[1..],
212+
&item.ident,
213+
)),
214+
)],
235215
),
236-
},
237-
),
238-
// test_type: ...
239-
field(
240-
"test_type",
241-
match test_type(cx) {
242-
// test::TestType::UnitTest
243-
TestType::UnitTest => {
244-
cx.expr_path(test_type_path("UnitTest"))
245-
}
246-
// test::TestType::IntegrationTest
247-
TestType::IntegrationTest => {
248-
cx.expr_path(test_type_path("IntegrationTest"))
249-
}
250-
// test::TestPath::Unknown
251-
TestType::Unknown => {
252-
cx.expr_path(test_type_path("Unknown"))
253-
}
254-
},
255-
),
256-
// },
257-
],
216+
),
217+
// ignore: true | false
218+
field("ignore", cx.expr_bool(sp, should_ignore(&item))),
219+
// allow_fail: true | false
220+
field("allow_fail", cx.expr_bool(sp, should_fail(&item))),
221+
// should_panic: ...
222+
field(
223+
"should_panic",
224+
match should_panic(cx, &item) {
225+
// test::ShouldPanic::No
226+
ShouldPanic::No => {
227+
cx.expr_path(should_panic_path("No"))
228+
}
229+
// test::ShouldPanic::Yes
230+
ShouldPanic::Yes(None) => {
231+
cx.expr_path(should_panic_path("Yes"))
232+
}
233+
// test::ShouldPanic::YesWithMessage("...")
234+
ShouldPanic::Yes(Some(sym)) => cx.expr_call(
235+
sp,
236+
cx.expr_path(should_panic_path("YesWithMessage")),
237+
vec![cx.expr_str(sp, sym)],
238+
),
239+
},
240+
),
241+
// test_type: ...
242+
field(
243+
"test_type",
244+
match test_type(cx) {
245+
// test::TestType::UnitTest
246+
TestType::UnitTest => {
247+
cx.expr_path(test_type_path("UnitTest"))
248+
}
249+
// test::TestType::IntegrationTest
250+
TestType::IntegrationTest => {
251+
cx.expr_path(test_type_path("IntegrationTest"))
252+
}
253+
// test::TestPath::Unknown
254+
TestType::Unknown => {
255+
cx.expr_path(test_type_path("Unknown"))
256+
}
257+
},
258+
),
259+
// },
260+
],
261+
),
258262
),
259-
),
260-
// testfn: test::StaticTestFn(...) | test::StaticBenchFn(...)
261-
field("testfn", test_fn), // }
262-
],
263-
), // }
263+
// testfn: test::StaticTestFn(...) | test::StaticBenchFn(...)
264+
field("testfn", test_fn), // }
265+
],
266+
), // }
267+
),
264268
),
265269
);
266270
test_const = test_const.map(|mut tc| {

src/librustc_expand/build.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -634,7 +634,7 @@ impl<'a> ExtCtxt<'a> {
634634
mutbl: ast::Mutability,
635635
expr: P<ast::Expr>,
636636
) -> P<ast::Item> {
637-
self.item(span, name, Vec::new(), ast::ItemKind::Static(ty, mutbl, expr))
637+
self.item(span, name, Vec::new(), ast::ItemKind::Static(ty, mutbl, Some(expr)))
638638
}
639639

640640
pub fn item_const(
@@ -644,7 +644,7 @@ impl<'a> ExtCtxt<'a> {
644644
ty: P<ast::Ty>,
645645
expr: P<ast::Expr>,
646646
) -> P<ast::Item> {
647-
self.item(span, name, Vec::new(), ast::ItemKind::Const(ty, expr))
647+
self.item(span, name, Vec::new(), ast::ItemKind::Const(ty, Some(expr)))
648648
}
649649

650650
pub fn attribute(&self, mi: ast::MetaItem) -> ast::Attribute {

src/librustc_lint/unused.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -603,7 +603,7 @@ impl EarlyLintPass for UnusedParens {
603603
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) {
604604
use ast::ItemKind::*;
605605

606-
if let Const(.., ref expr) | Static(.., ref expr) = item.kind {
606+
if let Const(.., Some(expr)) | Static(.., Some(expr)) = &item.kind {
607607
self.check_unused_parens_expr(cx, expr, "assigned value", false, None, None);
608608
}
609609
}

src/librustc_parse/parser/item.rs

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -966,7 +966,7 @@ impl<'a> Parser<'a> {
966966
}
967967
}
968968

969-
/// Parse `["const" | ("static" "mut"?)] $ident ":" $ty = $expr` with
969+
/// Parse `["const" | ("static" "mut"?)] $ident ":" $ty (= $expr)?` with
970970
/// `["const" | ("static" "mut"?)]` already parsed and stored in `m`.
971971
///
972972
/// When `m` is `"const"`, `$ident` may also be `"_"`.
@@ -975,25 +975,22 @@ impl<'a> Parser<'a> {
975975

976976
// Parse the type of a `const` or `static mut?` item.
977977
// That is, the `":" $ty` fragment.
978-
let ty = if self.token == token::Eq {
979-
self.recover_missing_const_type(id, m)
980-
} else {
981-
// Not `=` so expect `":"" $ty` as usual.
982-
self.expect(&token::Colon)?;
978+
let ty = if self.eat(&token::Colon) {
983979
self.parse_ty()?
980+
} else {
981+
self.recover_missing_const_type(id, m)
984982
};
985983

986-
self.expect(&token::Eq)?;
987-
let e = self.parse_expr()?;
984+
let expr = if self.eat(&token::Eq) { Some(self.parse_expr()?) } else { None };
988985
self.expect_semi()?;
989986
let item = match m {
990-
Some(m) => ItemKind::Static(ty, m, e),
991-
None => ItemKind::Const(ty, e),
987+
Some(m) => ItemKind::Static(ty, m, expr),
988+
None => ItemKind::Const(ty, expr),
992989
};
993990
Ok((id, item))
994991
}
995992

996-
/// We were supposed to parse `:` but instead, we're already at `=`.
993+
/// We were supposed to parse `:` but the `:` was missing.
997994
/// This means that the type is missing.
998995
fn recover_missing_const_type(&mut self, id: Ident, m: Option<Mutability>) -> P<Ty> {
999996
// Construct the error and stash it away with the hope

src/librustc_resolve/late.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -881,9 +881,9 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
881881
debug!("resolve_item ItemKind::Const");
882882
self.with_item_rib(HasGenericParams::No, |this| {
883883
this.visit_ty(ty);
884-
this.with_constant_rib(|this| {
885-
this.visit_expr(expr);
886-
});
884+
if let Some(expr) = expr {
885+
this.with_constant_rib(|this| this.visit_expr(expr));
886+
}
887887
});
888888
}
889889

src/librustc_save_analysis/dump_visitor.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
400400
&mut self,
401401
item: &'l ast::Item,
402402
typ: &'l ast::Ty,
403-
expr: &'l ast::Expr,
403+
expr: Option<&'l ast::Expr>,
404404
) {
405405
let hir_id = self.tcx.hir().node_to_hir_id(item.id);
406406
self.nest_tables(item.id, |v| {
@@ -409,7 +409,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
409409
v.dumper.dump_def(&access_from!(v.save_ctxt, item, hir_id), var_data);
410410
}
411411
v.visit_ty(&typ);
412-
v.visit_expr(expr);
412+
walk_list!(v, visit_expr, expr);
413413
});
414414
}
415415

@@ -1293,8 +1293,8 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> {
12931293
Fn(ref sig, ref ty_params, ref body) => {
12941294
self.process_fn(item, &sig.decl, &sig.header, ty_params, body.as_deref())
12951295
}
1296-
Static(ref typ, _, ref expr) => self.process_static_or_const_item(item, typ, expr),
1297-
Const(ref typ, ref expr) => self.process_static_or_const_item(item, &typ, &expr),
1296+
Static(ref typ, _, ref e) => self.process_static_or_const_item(item, typ, e.as_deref()),
1297+
Const(ref typ, ref e) => self.process_static_or_const_item(item, typ, e.as_deref()),
12981298
Struct(ref def, ref ty_params) | Union(ref def, ref ty_params) => {
12991299
self.process_struct(item, def, ty_params)
13001300
}

src/librustc_save_analysis/sig.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -334,10 +334,13 @@ impl Sig for ast::Item {
334334

335335
let ty = ty.make(offset + text.len(), id, scx)?;
336336
text.push_str(&ty.text);
337-
text.push_str(" = ");
338337

339-
let expr = pprust::expr_to_string(expr).replace('\n', " ");
340-
text.push_str(&expr);
338+
if let Some(expr) = expr {
339+
text.push_str(" = ");
340+
let expr = pprust::expr_to_string(expr).replace('\n', " ");
341+
text.push_str(&expr);
342+
}
343+
341344
text.push(';');
342345

343346
Ok(extend_sig(ty, text, defs, vec![]))
@@ -355,10 +358,13 @@ impl Sig for ast::Item {
355358

356359
let ty = ty.make(offset + text.len(), id, scx)?;
357360
text.push_str(&ty.text);
358-
text.push_str(" = ");
359361

360-
let expr = pprust::expr_to_string(expr).replace('\n', " ");
361-
text.push_str(&expr);
362+
if let Some(expr) = expr {
363+
text.push_str(" = ");
364+
let expr = pprust::expr_to_string(expr).replace('\n', " ");
365+
text.push_str(&expr);
366+
}
367+
362368
text.push(';');
363369

364370
Ok(extend_sig(ty, text, defs, vec![]))

0 commit comments

Comments
 (0)