diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 0c313ab14899f..4b076ac364239 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -118,6 +118,20 @@ impl Annotatable { } } + pub fn expect_stmt(self) -> ast::Stmt { + match self { + Annotatable::Stmt(stmt) => stmt.into_inner(), + _ => panic!("expected statement"), + } + } + + pub fn expect_expr(self) -> P { + match self { + Annotatable::Expr(expr) => expr, + _ => panic!("expected expression"), + } + } + pub fn derive_allowed(&self) -> bool { match *self { Annotatable::Item(ref item) => match item.node { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 678c20402d6f4..e11c8988ab41d 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -143,7 +143,7 @@ impl ExpansionKind { } fn expect_from_annotatables>(self, items: I) -> Expansion { - let items = items.into_iter(); + let mut items = items.into_iter(); match self { ExpansionKind::Items => Expansion::Items(items.map(Annotatable::expect_item).collect()), @@ -153,7 +153,14 @@ impl ExpansionKind { Expansion::TraitItems(items.map(Annotatable::expect_trait_item).collect()), ExpansionKind::ForeignItems => Expansion::ForeignItems(items.map(Annotatable::expect_foreign_item).collect()), - _ => unreachable!(), + ExpansionKind::Stmts => Expansion::Stmts(items.map(Annotatable::expect_stmt).collect()), + ExpansionKind::Expr => Expansion::Expr( + items.next().expect("expected exactly one expression").expect_expr() + ), + ExpansionKind::OptExpr => + Expansion::OptExpr(items.next().map(Annotatable::expect_expr)), + ExpansionKind::Pat | ExpansionKind::Ty => + panic!("patterns and types aren't annotatable"), } } } diff --git a/src/test/compile-fail/issue-49934.rs b/src/test/compile-fail/issue-49934.rs new file mode 100644 index 0000000000000..996ddcce3a4ed --- /dev/null +++ b/src/test/compile-fail/issue-49934.rs @@ -0,0 +1,23 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. +#![feature(stmt_expr_attributes)] + +fn main() { + #[derive(Debug)] //~ ERROR `derive` + println!("Hello, world!"); + + let _ = #[derive(Debug)] "Hello, world!"; + //~^ ERROR `derive` + + let _ = [ + #[derive(Debug)] //~ ERROR `derive` + "Hello, world!" + ]; +}