mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-04 11:04:03 +00:00
ast: make = <expr>;
optional in free statics/consts.
This commit is contained in:
parent
95dc9b9a73
commit
f3e9763543
@ -269,26 +269,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
self.lower_use_tree(use_tree, &prefix, id, vis, ident, attrs)
|
||||
}
|
||||
ItemKind::Static(ref t, m, ref e) => {
|
||||
let ty = self.lower_ty(
|
||||
t,
|
||||
if self.sess.features_untracked().impl_trait_in_bindings {
|
||||
ImplTraitContext::OpaqueTy(None, hir::OpaqueTyOrigin::Misc)
|
||||
} else {
|
||||
ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
|
||||
},
|
||||
);
|
||||
hir::ItemKind::Static(ty, m, self.lower_const_body(span, Some(e)))
|
||||
let (ty, body_id) = self.lower_const_item(t, span, e.as_deref());
|
||||
hir::ItemKind::Static(ty, m, body_id)
|
||||
}
|
||||
ItemKind::Const(ref t, ref e) => {
|
||||
let ty = self.lower_ty(
|
||||
t,
|
||||
if self.sess.features_untracked().impl_trait_in_bindings {
|
||||
ImplTraitContext::OpaqueTy(None, hir::OpaqueTyOrigin::Misc)
|
||||
} else {
|
||||
ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
|
||||
},
|
||||
);
|
||||
hir::ItemKind::Const(ty, self.lower_const_body(span, Some(e)))
|
||||
let (ty, body_id) = self.lower_const_item(t, span, e.as_deref());
|
||||
hir::ItemKind::Const(ty, body_id)
|
||||
}
|
||||
ItemKind::Fn(FnSig { ref decl, header }, ref generics, ref body) => {
|
||||
let fn_def_id = self.resolver.definitions().local_def_id(id);
|
||||
@ -457,6 +443,21 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
// not cause an assertion failure inside the `lower_defaultness` function.
|
||||
}
|
||||
|
||||
fn lower_const_item(
|
||||
&mut self,
|
||||
ty: &Ty,
|
||||
span: Span,
|
||||
body: Option<&Expr>,
|
||||
) -> (&'hir hir::Ty<'hir>, hir::BodyId) {
|
||||
let itctx = if self.sess.features_untracked().impl_trait_in_bindings {
|
||||
ImplTraitContext::OpaqueTy(None, hir::OpaqueTyOrigin::Misc)
|
||||
} else {
|
||||
ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
|
||||
};
|
||||
let ty = self.lower_ty(ty, itctx);
|
||||
(ty, self.lower_const_body(span, body))
|
||||
}
|
||||
|
||||
fn lower_use_tree(
|
||||
&mut self,
|
||||
tree: &UseTree,
|
||||
|
@ -948,6 +948,14 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
self.err_handler().span_err(item.span, "unions cannot have zero fields");
|
||||
}
|
||||
}
|
||||
ItemKind::Const(.., None) => {
|
||||
let msg = "free constant item without body";
|
||||
self.error_item_without_body(item.span, "constant", msg, " = <expr>;");
|
||||
}
|
||||
ItemKind::Static(.., None) => {
|
||||
let msg = "free static item without body";
|
||||
self.error_item_without_body(item.span, "static", msg, " = <expr>;");
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
|
@ -1124,9 +1124,10 @@ impl<'a> State<'a> {
|
||||
self.print_type(ty);
|
||||
self.s.space();
|
||||
self.end(); // end the head-ibox
|
||||
|
||||
self.word_space("=");
|
||||
self.print_expr(expr);
|
||||
if let Some(expr) = expr {
|
||||
self.word_space("=");
|
||||
self.print_expr(expr);
|
||||
}
|
||||
self.s.word(";");
|
||||
self.end(); // end the outer cbox
|
||||
}
|
||||
@ -1137,9 +1138,10 @@ impl<'a> State<'a> {
|
||||
self.print_type(ty);
|
||||
self.s.space();
|
||||
self.end(); // end the head-ibox
|
||||
|
||||
self.word_space("=");
|
||||
self.print_expr(expr);
|
||||
if let Some(expr) = expr {
|
||||
self.word_space("=");
|
||||
self.print_expr(expr);
|
||||
}
|
||||
self.s.word(";");
|
||||
self.end(); // end the outer cbox
|
||||
}
|
||||
|
@ -186,81 +186,85 @@ pub fn expand_test_or_bench(
|
||||
ast::ItemKind::Const(
|
||||
cx.ty(sp, ast::TyKind::Path(None, test_path("TestDescAndFn"))),
|
||||
// test::TestDescAndFn {
|
||||
cx.expr_struct(
|
||||
sp,
|
||||
test_path("TestDescAndFn"),
|
||||
vec![
|
||||
// desc: test::TestDesc {
|
||||
field(
|
||||
"desc",
|
||||
cx.expr_struct(
|
||||
sp,
|
||||
test_path("TestDesc"),
|
||||
vec![
|
||||
// name: "path::to::test"
|
||||
field(
|
||||
"name",
|
||||
cx.expr_call(
|
||||
sp,
|
||||
cx.expr_path(test_path("StaticTestName")),
|
||||
vec![cx.expr_str(
|
||||
Some(
|
||||
cx.expr_struct(
|
||||
sp,
|
||||
test_path("TestDescAndFn"),
|
||||
vec![
|
||||
// desc: test::TestDesc {
|
||||
field(
|
||||
"desc",
|
||||
cx.expr_struct(
|
||||
sp,
|
||||
test_path("TestDesc"),
|
||||
vec![
|
||||
// name: "path::to::test"
|
||||
field(
|
||||
"name",
|
||||
cx.expr_call(
|
||||
sp,
|
||||
Symbol::intern(&item_path(
|
||||
// skip the name of the root module
|
||||
&cx.current_expansion.module.mod_path[1..],
|
||||
&item.ident,
|
||||
)),
|
||||
)],
|
||||
),
|
||||
),
|
||||
// ignore: true | false
|
||||
field("ignore", cx.expr_bool(sp, should_ignore(&item))),
|
||||
// allow_fail: true | false
|
||||
field("allow_fail", cx.expr_bool(sp, should_fail(&item))),
|
||||
// should_panic: ...
|
||||
field(
|
||||
"should_panic",
|
||||
match should_panic(cx, &item) {
|
||||
// test::ShouldPanic::No
|
||||
ShouldPanic::No => cx.expr_path(should_panic_path("No")),
|
||||
// test::ShouldPanic::Yes
|
||||
ShouldPanic::Yes(None) => {
|
||||
cx.expr_path(should_panic_path("Yes"))
|
||||
}
|
||||
// test::ShouldPanic::YesWithMessage("...")
|
||||
ShouldPanic::Yes(Some(sym)) => cx.expr_call(
|
||||
sp,
|
||||
cx.expr_path(should_panic_path("YesWithMessage")),
|
||||
vec![cx.expr_str(sp, sym)],
|
||||
cx.expr_path(test_path("StaticTestName")),
|
||||
vec![cx.expr_str(
|
||||
sp,
|
||||
Symbol::intern(&item_path(
|
||||
// skip the name of the root module
|
||||
&cx.current_expansion.module.mod_path[1..],
|
||||
&item.ident,
|
||||
)),
|
||||
)],
|
||||
),
|
||||
},
|
||||
),
|
||||
// test_type: ...
|
||||
field(
|
||||
"test_type",
|
||||
match test_type(cx) {
|
||||
// test::TestType::UnitTest
|
||||
TestType::UnitTest => {
|
||||
cx.expr_path(test_type_path("UnitTest"))
|
||||
}
|
||||
// test::TestType::IntegrationTest
|
||||
TestType::IntegrationTest => {
|
||||
cx.expr_path(test_type_path("IntegrationTest"))
|
||||
}
|
||||
// test::TestPath::Unknown
|
||||
TestType::Unknown => {
|
||||
cx.expr_path(test_type_path("Unknown"))
|
||||
}
|
||||
},
|
||||
),
|
||||
// },
|
||||
],
|
||||
),
|
||||
// ignore: true | false
|
||||
field("ignore", cx.expr_bool(sp, should_ignore(&item))),
|
||||
// allow_fail: true | false
|
||||
field("allow_fail", cx.expr_bool(sp, should_fail(&item))),
|
||||
// should_panic: ...
|
||||
field(
|
||||
"should_panic",
|
||||
match should_panic(cx, &item) {
|
||||
// test::ShouldPanic::No
|
||||
ShouldPanic::No => {
|
||||
cx.expr_path(should_panic_path("No"))
|
||||
}
|
||||
// test::ShouldPanic::Yes
|
||||
ShouldPanic::Yes(None) => {
|
||||
cx.expr_path(should_panic_path("Yes"))
|
||||
}
|
||||
// test::ShouldPanic::YesWithMessage("...")
|
||||
ShouldPanic::Yes(Some(sym)) => cx.expr_call(
|
||||
sp,
|
||||
cx.expr_path(should_panic_path("YesWithMessage")),
|
||||
vec![cx.expr_str(sp, sym)],
|
||||
),
|
||||
},
|
||||
),
|
||||
// test_type: ...
|
||||
field(
|
||||
"test_type",
|
||||
match test_type(cx) {
|
||||
// test::TestType::UnitTest
|
||||
TestType::UnitTest => {
|
||||
cx.expr_path(test_type_path("UnitTest"))
|
||||
}
|
||||
// test::TestType::IntegrationTest
|
||||
TestType::IntegrationTest => {
|
||||
cx.expr_path(test_type_path("IntegrationTest"))
|
||||
}
|
||||
// test::TestPath::Unknown
|
||||
TestType::Unknown => {
|
||||
cx.expr_path(test_type_path("Unknown"))
|
||||
}
|
||||
},
|
||||
),
|
||||
// },
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
// testfn: test::StaticTestFn(...) | test::StaticBenchFn(...)
|
||||
field("testfn", test_fn), // }
|
||||
],
|
||||
), // }
|
||||
// testfn: test::StaticTestFn(...) | test::StaticBenchFn(...)
|
||||
field("testfn", test_fn), // }
|
||||
],
|
||||
), // }
|
||||
),
|
||||
),
|
||||
);
|
||||
test_const = test_const.map(|mut tc| {
|
||||
|
@ -634,7 +634,7 @@ impl<'a> ExtCtxt<'a> {
|
||||
mutbl: ast::Mutability,
|
||||
expr: P<ast::Expr>,
|
||||
) -> P<ast::Item> {
|
||||
self.item(span, name, Vec::new(), ast::ItemKind::Static(ty, mutbl, expr))
|
||||
self.item(span, name, Vec::new(), ast::ItemKind::Static(ty, mutbl, Some(expr)))
|
||||
}
|
||||
|
||||
pub fn item_const(
|
||||
@ -644,7 +644,7 @@ impl<'a> ExtCtxt<'a> {
|
||||
ty: P<ast::Ty>,
|
||||
expr: P<ast::Expr>,
|
||||
) -> P<ast::Item> {
|
||||
self.item(span, name, Vec::new(), ast::ItemKind::Const(ty, expr))
|
||||
self.item(span, name, Vec::new(), ast::ItemKind::Const(ty, Some(expr)))
|
||||
}
|
||||
|
||||
pub fn attribute(&self, mi: ast::MetaItem) -> ast::Attribute {
|
||||
|
@ -603,7 +603,7 @@ impl EarlyLintPass for UnusedParens {
|
||||
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) {
|
||||
use ast::ItemKind::*;
|
||||
|
||||
if let Const(.., ref expr) | Static(.., ref expr) = item.kind {
|
||||
if let Const(.., Some(expr)) | Static(.., Some(expr)) = &item.kind {
|
||||
self.check_unused_parens_expr(cx, expr, "assigned value", false, None, None);
|
||||
}
|
||||
}
|
||||
|
@ -966,7 +966,7 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse `["const" | ("static" "mut"?)] $ident ":" $ty = $expr` with
|
||||
/// Parse `["const" | ("static" "mut"?)] $ident ":" $ty (= $expr)?` with
|
||||
/// `["const" | ("static" "mut"?)]` already parsed and stored in `m`.
|
||||
///
|
||||
/// When `m` is `"const"`, `$ident` may also be `"_"`.
|
||||
@ -975,25 +975,22 @@ impl<'a> Parser<'a> {
|
||||
|
||||
// Parse the type of a `const` or `static mut?` item.
|
||||
// That is, the `":" $ty` fragment.
|
||||
let ty = if self.token == token::Eq {
|
||||
self.recover_missing_const_type(id, m)
|
||||
} else {
|
||||
// Not `=` so expect `":"" $ty` as usual.
|
||||
self.expect(&token::Colon)?;
|
||||
let ty = if self.eat(&token::Colon) {
|
||||
self.parse_ty()?
|
||||
} else {
|
||||
self.recover_missing_const_type(id, m)
|
||||
};
|
||||
|
||||
self.expect(&token::Eq)?;
|
||||
let e = self.parse_expr()?;
|
||||
let expr = if self.eat(&token::Eq) { Some(self.parse_expr()?) } else { None };
|
||||
self.expect_semi()?;
|
||||
let item = match m {
|
||||
Some(m) => ItemKind::Static(ty, m, e),
|
||||
None => ItemKind::Const(ty, e),
|
||||
Some(m) => ItemKind::Static(ty, m, expr),
|
||||
None => ItemKind::Const(ty, expr),
|
||||
};
|
||||
Ok((id, item))
|
||||
}
|
||||
|
||||
/// We were supposed to parse `:` but instead, we're already at `=`.
|
||||
/// We were supposed to parse `:` but the `:` was missing.
|
||||
/// This means that the type is missing.
|
||||
fn recover_missing_const_type(&mut self, id: Ident, m: Option<Mutability>) -> P<Ty> {
|
||||
// Construct the error and stash it away with the hope
|
||||
|
@ -881,9 +881,9 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
||||
debug!("resolve_item ItemKind::Const");
|
||||
self.with_item_rib(HasGenericParams::No, |this| {
|
||||
this.visit_ty(ty);
|
||||
this.with_constant_rib(|this| {
|
||||
this.visit_expr(expr);
|
||||
});
|
||||
if let Some(expr) = expr {
|
||||
this.with_constant_rib(|this| this.visit_expr(expr));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -400,7 +400,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
|
||||
&mut self,
|
||||
item: &'l ast::Item,
|
||||
typ: &'l ast::Ty,
|
||||
expr: &'l ast::Expr,
|
||||
expr: Option<&'l ast::Expr>,
|
||||
) {
|
||||
let hir_id = self.tcx.hir().node_to_hir_id(item.id);
|
||||
self.nest_tables(item.id, |v| {
|
||||
@ -409,7 +409,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
|
||||
v.dumper.dump_def(&access_from!(v.save_ctxt, item, hir_id), var_data);
|
||||
}
|
||||
v.visit_ty(&typ);
|
||||
v.visit_expr(expr);
|
||||
walk_list!(v, visit_expr, expr);
|
||||
});
|
||||
}
|
||||
|
||||
@ -1293,8 +1293,8 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> {
|
||||
Fn(ref sig, ref ty_params, ref body) => {
|
||||
self.process_fn(item, &sig.decl, &sig.header, ty_params, body.as_deref())
|
||||
}
|
||||
Static(ref typ, _, ref expr) => self.process_static_or_const_item(item, typ, expr),
|
||||
Const(ref typ, ref expr) => self.process_static_or_const_item(item, &typ, &expr),
|
||||
Static(ref typ, _, ref e) => self.process_static_or_const_item(item, typ, e.as_deref()),
|
||||
Const(ref typ, ref e) => self.process_static_or_const_item(item, typ, e.as_deref()),
|
||||
Struct(ref def, ref ty_params) | Union(ref def, ref ty_params) => {
|
||||
self.process_struct(item, def, ty_params)
|
||||
}
|
||||
|
@ -334,10 +334,13 @@ impl Sig for ast::Item {
|
||||
|
||||
let ty = ty.make(offset + text.len(), id, scx)?;
|
||||
text.push_str(&ty.text);
|
||||
text.push_str(" = ");
|
||||
|
||||
let expr = pprust::expr_to_string(expr).replace('\n', " ");
|
||||
text.push_str(&expr);
|
||||
if let Some(expr) = expr {
|
||||
text.push_str(" = ");
|
||||
let expr = pprust::expr_to_string(expr).replace('\n', " ");
|
||||
text.push_str(&expr);
|
||||
}
|
||||
|
||||
text.push(';');
|
||||
|
||||
Ok(extend_sig(ty, text, defs, vec![]))
|
||||
@ -355,10 +358,13 @@ impl Sig for ast::Item {
|
||||
|
||||
let ty = ty.make(offset + text.len(), id, scx)?;
|
||||
text.push_str(&ty.text);
|
||||
text.push_str(" = ");
|
||||
|
||||
let expr = pprust::expr_to_string(expr).replace('\n', " ");
|
||||
text.push_str(&expr);
|
||||
if let Some(expr) = expr {
|
||||
text.push_str(" = ");
|
||||
let expr = pprust::expr_to_string(expr).replace('\n', " ");
|
||||
text.push_str(&expr);
|
||||
}
|
||||
|
||||
text.push(';');
|
||||
|
||||
Ok(extend_sig(ty, text, defs, vec![]))
|
||||
|
@ -2496,11 +2496,11 @@ pub enum ItemKind {
|
||||
/// A static item (`static`).
|
||||
///
|
||||
/// E.g., `static FOO: i32 = 42;` or `static FOO: &'static str = "bar";`.
|
||||
Static(P<Ty>, Mutability, P<Expr>),
|
||||
Static(P<Ty>, Mutability, Option<P<Expr>>),
|
||||
/// A constant item (`const`).
|
||||
///
|
||||
/// E.g., `const FOO: i32 = 42;`.
|
||||
Const(P<Ty>, P<Expr>),
|
||||
Const(P<Ty>, Option<P<Expr>>),
|
||||
/// A function declaration (`fn`).
|
||||
///
|
||||
/// E.g., `fn foo(bar: usize) -> usize { .. }`.
|
||||
|
@ -890,13 +890,9 @@ pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) {
|
||||
match kind {
|
||||
ItemKind::ExternCrate(_orig_name) => {}
|
||||
ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree),
|
||||
ItemKind::Static(ty, _mut, expr) => {
|
||||
ItemKind::Static(ty, _, expr) | ItemKind::Const(ty, expr) => {
|
||||
vis.visit_ty(ty);
|
||||
vis.visit_expr(expr);
|
||||
}
|
||||
ItemKind::Const(ty, expr) => {
|
||||
vis.visit_ty(ty);
|
||||
vis.visit_expr(expr);
|
||||
visit_opt(expr, |expr| vis.visit_expr(expr));
|
||||
}
|
||||
ItemKind::Fn(sig, generics, body) => {
|
||||
visit_fn_sig(sig, vis);
|
||||
|
@ -300,7 +300,7 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
|
||||
ItemKind::Use(ref use_tree) => visitor.visit_use_tree(use_tree, item.id, false),
|
||||
ItemKind::Static(ref typ, _, ref expr) | ItemKind::Const(ref typ, ref expr) => {
|
||||
visitor.visit_ty(typ);
|
||||
visitor.visit_expr(expr);
|
||||
walk_list!(visitor, visit_expr, expr);
|
||||
}
|
||||
ItemKind::Fn(ref sig, ref generics, ref body) => {
|
||||
visitor.visit_generics(generics);
|
||||
|
@ -0,0 +1,7 @@
|
||||
// Semantically, a free `const` item cannot omit its body.
|
||||
|
||||
fn main() {}
|
||||
|
||||
const A: u8; //~ ERROR free constant item without body
|
||||
const B; //~ ERROR free constant item without body
|
||||
//~^ ERROR missing type for `const` item
|
@ -0,0 +1,24 @@
|
||||
error: free constant item without body
|
||||
--> $DIR/item-free-const-no-body-semantic-fail.rs:5:1
|
||||
|
|
||||
LL | const A: u8;
|
||||
| ^^^^^^^^^^^-
|
||||
| |
|
||||
| help: provide a definition for the constant: `= <expr>;`
|
||||
|
||||
error: free constant item without body
|
||||
--> $DIR/item-free-const-no-body-semantic-fail.rs:6:1
|
||||
|
|
||||
LL | const B;
|
||||
| ^^^^^^^-
|
||||
| |
|
||||
| help: provide a definition for the constant: `= <expr>;`
|
||||
|
||||
error: missing type for `const` item
|
||||
--> $DIR/item-free-const-no-body-semantic-fail.rs:6:7
|
||||
|
|
||||
LL | const B;
|
||||
| ^ help: provide a type for the item: `B: [type error]`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
@ -0,0 +1,8 @@
|
||||
// Syntactically, a free `const` item can omit its body.
|
||||
|
||||
// check-pass
|
||||
|
||||
fn main() {}
|
||||
|
||||
#[cfg(FALSE)]
|
||||
const X: u8;
|
11
src/test/ui/parser/item-free-static-no-body-semantic-fail.rs
Normal file
11
src/test/ui/parser/item-free-static-no-body-semantic-fail.rs
Normal file
@ -0,0 +1,11 @@
|
||||
// Semantically, a free `static` item cannot omit its body.
|
||||
|
||||
fn main() {}
|
||||
|
||||
static A: u8; //~ ERROR free static item without body
|
||||
static B; //~ ERROR free static item without body
|
||||
//~^ ERROR missing type for `static` item
|
||||
|
||||
static mut C: u8; //~ ERROR free static item without body
|
||||
static mut D; //~ ERROR free static item without body
|
||||
//~^ ERROR missing type for `static mut` item
|
@ -0,0 +1,46 @@
|
||||
error: free static item without body
|
||||
--> $DIR/item-free-static-no-body-semantic-fail.rs:5:1
|
||||
|
|
||||
LL | static A: u8;
|
||||
| ^^^^^^^^^^^^-
|
||||
| |
|
||||
| help: provide a definition for the static: `= <expr>;`
|
||||
|
||||
error: free static item without body
|
||||
--> $DIR/item-free-static-no-body-semantic-fail.rs:6:1
|
||||
|
|
||||
LL | static B;
|
||||
| ^^^^^^^^-
|
||||
| |
|
||||
| help: provide a definition for the static: `= <expr>;`
|
||||
|
||||
error: free static item without body
|
||||
--> $DIR/item-free-static-no-body-semantic-fail.rs:9:1
|
||||
|
|
||||
LL | static mut C: u8;
|
||||
| ^^^^^^^^^^^^^^^^-
|
||||
| |
|
||||
| help: provide a definition for the static: `= <expr>;`
|
||||
|
||||
error: free static item without body
|
||||
--> $DIR/item-free-static-no-body-semantic-fail.rs:10:1
|
||||
|
|
||||
LL | static mut D;
|
||||
| ^^^^^^^^^^^^-
|
||||
| |
|
||||
| help: provide a definition for the static: `= <expr>;`
|
||||
|
||||
error: missing type for `static` item
|
||||
--> $DIR/item-free-static-no-body-semantic-fail.rs:6:8
|
||||
|
|
||||
LL | static B;
|
||||
| ^ help: provide a type for the item: `B: [type error]`
|
||||
|
||||
error: missing type for `static mut` item
|
||||
--> $DIR/item-free-static-no-body-semantic-fail.rs:10:12
|
||||
|
|
||||
LL | static mut D;
|
||||
| ^ help: provide a type for the item: `D: [type error]`
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
@ -0,0 +1,8 @@
|
||||
// Syntactically, a free `const` item can omit its body.
|
||||
|
||||
// check-pass
|
||||
|
||||
fn main() {}
|
||||
|
||||
#[cfg(FALSE)]
|
||||
static X: u8;
|
Loading…
Reference in New Issue
Block a user