Skip to content

Commit 73557fa

Browse files
committed
Use Option in ImplItemKind::Const.
1 parent c4bbe9c commit 73557fa

File tree

11 files changed

+66
-20
lines changed

11 files changed

+66
-20
lines changed

src/librustc/hir/lowering/item.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -899,7 +899,13 @@ impl LoweringContext<'_> {
899899
self.lower_generics(&i.generics, ImplTraitContext::disallowed()),
900900
hir::ImplItemKind::Const(
901901
self.lower_ty(ty, ImplTraitContext::disallowed()),
902-
self.lower_const_body(expr),
902+
match expr {
903+
Some(expr) => self.lower_const_body(expr),
904+
None => self.lower_body(|this| (
905+
hir_vec![],
906+
this.expr(i.span, hir::ExprKind::Err, ThinVec::new()),
907+
)),
908+
}
903909
),
904910
),
905911
ImplItemKind::Method(ref sig, ref body) => {

src/librustc_parse/parser/item.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -756,13 +756,16 @@ impl<'a> Parser<'a> {
756756
/// ImplItemConst = "const" Ident ":" Ty "=" Expr ";"
757757
fn parse_impl_const(&mut self) -> PResult<'a, (Ident, ImplItemKind, Generics)> {
758758
self.expect_keyword(kw::Const)?;
759-
let name = self.parse_ident()?;
759+
let ident = self.parse_ident()?;
760760
self.expect(&token::Colon)?;
761-
let typ = self.parse_ty()?;
762-
self.expect(&token::Eq)?;
763-
let expr = self.parse_expr()?;
761+
let ty = self.parse_ty()?;
762+
let expr = if self.eat(&token::Eq) {
763+
Some(self.parse_expr()?)
764+
} else {
765+
None
766+
};
764767
self.expect_semi()?;
765-
Ok((name, ImplItemKind::Const(typ, expr), Generics::default()))
768+
Ok((ident, ImplItemKind::Const(ty, expr), Generics::default()))
766769
}
767770

768771
/// Parses `auto? trait Foo { ... }` or `trait Foo = Bar;`.
@@ -912,13 +915,13 @@ impl<'a> Parser<'a> {
912915
let ident = self.parse_ident()?;
913916
self.expect(&token::Colon)?;
914917
let ty = self.parse_ty()?;
915-
let default = if self.eat(&token::Eq) {
918+
let expr = if self.eat(&token::Eq) {
916919
Some(self.parse_expr()?)
917920
} else {
918921
None
919922
};
920923
self.expect_semi()?;
921-
Ok((ident, TraitItemKind::Const(ty, default), Generics::default()))
924+
Ok((ident, TraitItemKind::Const(ty, expr), Generics::default()))
922925
}
923926

924927
/// Parses the following grammar:

src/librustc_passes/ast_validation.rs

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -259,12 +259,12 @@ impl<'a> AstValidator<'a> {
259259
!arr.contains(&attr.name_or_empty()) && attr::is_builtin_attr(attr)
260260
})
261261
.for_each(|attr| if attr.is_doc_comment() {
262-
let mut err = self.err_handler().struct_span_err(
262+
self.err_handler().struct_span_err(
263263
attr.span,
264264
"documentation comments cannot be applied to function parameters"
265-
);
266-
err.span_label(attr.span, "doc comments are not allowed here");
267-
err.emit();
265+
)
266+
.span_label(attr.span, "doc comments are not allowed here")
267+
.emit();
268268
}
269269
else {
270270
self.err_handler().span_err(attr.span, "allow, cfg, cfg_attr, deny, \
@@ -746,8 +746,22 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
746746
}
747747

748748
fn visit_impl_item(&mut self, ii: &'a ImplItem) {
749-
if let ImplItemKind::Method(ref sig, _) = ii.kind {
750-
self.check_fn_decl(&sig.decl);
749+
match &ii.kind {
750+
ImplItemKind::Const(ty, None) => {
751+
self.err_handler()
752+
.struct_span_err(ii.span, "associated constant in `impl` without body")
753+
.span_suggestion(
754+
ii.span,
755+
"provide a definition for the constant",
756+
format!("const {}: {} = <expr>;", ii.ident, pprust::ty_to_string(ty)),
757+
Applicability::HasPlaceholders,
758+
)
759+
.emit();
760+
}
761+
ImplItemKind::Method(sig, _) => {
762+
self.check_fn_decl(&sig.decl);
763+
}
764+
_ => {}
751765
}
752766
visit::walk_impl_item(self, ii);
753767
}

src/librustc_save_analysis/dump_visitor.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1110,7 +1110,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
11101110
impl_item.id,
11111111
impl_item.ident,
11121112
&ty,
1113-
Some(expr),
1113+
expr.as_deref(),
11141114
impl_id,
11151115
impl_item.vis.clone(),
11161116
&impl_item.attrs,

src/libsyntax/ast.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1635,8 +1635,8 @@ pub struct ImplItem<K = ImplItemKind> {
16351635

16361636
/// Represents various kinds of content within an `impl`.
16371637
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1638-
pub enum ImplItemKind {
1639-
Const(P<Ty>, P<Expr>),
1638+
pub enum ImplItemKind {
1639+
Const(P<Ty>, Option<P<Expr>>),
16401640
Method(FnSig, P<Block>),
16411641
TyAlias(P<Ty>),
16421642
Macro(Mac),

src/libsyntax/mut_visit.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -981,7 +981,7 @@ pub fn noop_flat_map_impl_item<T: MutVisitor>(mut item: ImplItem, visitor: &mut
981981
match kind {
982982
ImplItemKind::Const(ty, expr) => {
983983
visitor.visit_ty(ty);
984-
visitor.visit_expr(expr);
984+
visit_opt(expr, |expr| visitor.visit_expr(expr));
985985
}
986986
ImplItemKind::Method(sig, body) => {
987987
visit_fn_sig(sig, visitor);

src/libsyntax/print/pprust.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1599,7 +1599,7 @@ impl<'a> State<'a> {
15991599
self.print_defaultness(ii.defaultness);
16001600
match ii.kind {
16011601
ast::ImplItemKind::Const(ref ty, ref expr) => {
1602-
self.print_associated_const(ii.ident, ty, Some(expr), &ii.vis);
1602+
self.print_associated_const(ii.ident, ty, expr.as_deref(), &ii.vis);
16031603
}
16041604
ast::ImplItemKind::Method(ref sig, ref body) => {
16051605
self.head("");

src/libsyntax/visit.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -617,7 +617,7 @@ pub fn walk_impl_item<'a, V: Visitor<'a>>(visitor: &mut V, impl_item: &'a ImplIt
617617
match impl_item.kind {
618618
ImplItemKind::Const(ref ty, ref expr) => {
619619
visitor.visit_ty(ty);
620-
visitor.visit_expr(expr);
620+
walk_list!(visitor, visit_expr, expr);
621621
}
622622
ImplItemKind::Method(ref sig, ref body) => {
623623
visitor.visit_fn(FnKind::Method(impl_item.ident, sig, Some(&impl_item.vis), body),
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// check-pass
2+
3+
fn main() {}
4+
5+
#[cfg(FALSE)]
6+
impl X {
7+
const Y: u8;
8+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
fn main() {}
2+
3+
struct X;
4+
5+
impl X {
6+
const Y: u8; //~ ERROR associated constant in `impl` without body
7+
}

0 commit comments

Comments
 (0)