Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implements RFC 16, attributes on statements and expressions. #29850

Merged
merged 12 commits into from
Dec 4, 2015
3 changes: 3 additions & 0 deletions src/doc/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -2368,6 +2368,9 @@ The currently implemented features of the reference compiler are:
influence type inference.
* - `braced_empty_structs` - Allows use of empty structs and enum variants with braces.

* - `stmt_expr_attributes` - Allows attributes on expressions and
non-item statements.

If a feature is promoted to a language feature, then all existing programs will
start to receive compilation warnings about `#![feature]` directives which enabled
the new feature (because the directive is no longer necessary). However, if a
Expand Down
18 changes: 14 additions & 4 deletions src/librustc/lint/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ use syntax::attr::{self, AttrMetaMethods};
use syntax::codemap::Span;
use syntax::parse::token::InternedString;
use syntax::ast;
use syntax::attr::ThinAttributesExt;
use rustc_front::hir;
use rustc_front::util;
use rustc_front::intravisit as hir_visit;
Expand Down Expand Up @@ -674,11 +675,18 @@ impl<'a, 'tcx, 'v> hir_visit::Visitor<'v> for LateContext<'a, 'tcx> {
}

fn visit_expr(&mut self, e: &hir::Expr) {
run_lints!(self, check_expr, late_passes, e);
hir_visit::walk_expr(self, e);
self.with_lint_attrs(e.attrs.as_attr_slice(), |cx| {
run_lints!(cx, check_expr, late_passes, e);
hir_visit::walk_expr(cx, e);
})
}

fn visit_stmt(&mut self, s: &hir::Stmt) {
// statement attributes are actually just attributes on one of
// - item
// - local
// - expression
// so we keep track of lint levels there
run_lints!(self, check_stmt, late_passes, s);
hir_visit::walk_stmt(self, s);
}
Expand Down Expand Up @@ -730,8 +738,10 @@ impl<'a, 'tcx, 'v> hir_visit::Visitor<'v> for LateContext<'a, 'tcx> {
}

fn visit_local(&mut self, l: &hir::Local) {
run_lints!(self, check_local, late_passes, l);
hir_visit::walk_local(self, l);
self.with_lint_attrs(l.attrs.as_attr_slice(), |cx| {
run_lints!(cx, check_local, late_passes, l);
hir_visit::walk_local(cx, l);
})
}

fn visit_block(&mut self, b: &hir::Block) {
Expand Down
3 changes: 2 additions & 1 deletion src/librustc/middle/check_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,8 @@ fn const_val_to_expr(value: &ConstVal) -> P<hir::Expr> {
P(hir::Expr {
id: 0,
node: hir::ExprLit(P(Spanned { node: node, span: DUMMY_SP })),
span: DUMMY_SP
span: DUMMY_SP,
attrs: None,
})
}

Expand Down
1 change: 1 addition & 0 deletions src/librustc_driver/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -654,6 +654,7 @@ impl fold::Folder for ReplaceBodyWithLoop {
node: ast::ExprLoop(empty_block, None),
id: ast::DUMMY_NODE_ID,
span: codemap::DUMMY_SP,
attrs: None,
});

expr_to_block(b.rules, Some(loop_expr))
Expand Down
51 changes: 12 additions & 39 deletions src/librustc_front/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,39 +14,13 @@
use hir::*;
use syntax::ast::{Ident, Name, NodeId, DUMMY_NODE_ID, Attribute, Attribute_, MetaItem};
use syntax::ast::{MetaWord, MetaList, MetaNameValue};
use syntax::attr::ThinAttributesExt;
use hir;
use syntax::codemap::{respan, Span, Spanned};
use syntax::owned_slice::OwnedSlice;
use syntax::ptr::P;
use syntax::parse::token;
use std::ptr;

// This could have a better place to live.
pub trait MoveMap<T> {
fn move_map<F>(self, f: F) -> Self where F: FnMut(T) -> T;
}

impl<T> MoveMap<T> for Vec<T> {
fn move_map<F>(mut self, mut f: F) -> Vec<T>
where F: FnMut(T) -> T
{
for p in &mut self {
unsafe {
// FIXME(#5016) this shouldn't need to zero to be safe.
ptr::write(p, f(ptr::read_and_drop(p)));
}
}
self
}
}

impl<T> MoveMap<T> for OwnedSlice<T> {
fn move_map<F>(self, f: F) -> OwnedSlice<T>
where F: FnMut(T) -> T
{
OwnedSlice::from_vec(self.into_vec().move_map(f))
}
}
use syntax::util::move_map::MoveMap;

pub trait Folder : Sized {
// Any additions to this trait should happen in form
Expand Down Expand Up @@ -332,7 +306,7 @@ pub fn noop_fold_view_path<T: Folder>(view_path: P<ViewPath>, fld: &mut T) -> P<
}

pub fn fold_attrs<T: Folder>(attrs: Vec<Attribute>, fld: &mut T) -> Vec<Attribute> {
attrs.into_iter().flat_map(|x| fld.fold_attribute(x)).collect()
attrs.move_flat_map(|x| fld.fold_attribute(x))
}

pub fn noop_fold_arm<T: Folder>(Arm { attrs, pats, guard, body }: Arm, fld: &mut T) -> Arm {
Expand Down Expand Up @@ -501,13 +475,14 @@ pub fn noop_fold_parenthesized_parameter_data<T: Folder>(data: ParenthesizedPara
}

pub fn noop_fold_local<T: Folder>(l: P<Local>, fld: &mut T) -> P<Local> {
l.map(|Local { id, pat, ty, init, span }| {
l.map(|Local { id, pat, ty, init, span, attrs }| {
Local {
id: fld.new_id(id),
ty: ty.map(|t| fld.fold_ty(t)),
pat: fld.fold_pat(pat),
init: init.map(|e| fld.fold_expr(e)),
span: fld.new_span(span),
attrs: attrs.map_thin_attrs(|attrs| fold_attrs(attrs, fld)),
}
})
}
Expand Down Expand Up @@ -769,7 +744,7 @@ pub fn noop_fold_block<T: Folder>(b: P<Block>, folder: &mut T) -> P<Block> {
b.map(|Block { id, stmts, expr, rules, span }| {
Block {
id: folder.new_id(id),
stmts: stmts.into_iter().map(|s| folder.fold_stmt(s)).collect(),
stmts: stmts.move_map(|s| folder.fold_stmt(s)),
expr: expr.map(|x| folder.fold_expr(x)),
rules: rules,
span: folder.new_span(span),
Expand Down Expand Up @@ -816,9 +791,8 @@ pub fn noop_fold_item_underscore<T: Folder>(i: Item_, folder: &mut T) -> Item_ {
ItemDefaultImpl(unsafety, folder.fold_trait_ref((*trait_ref).clone()))
}
ItemImpl(unsafety, polarity, generics, ifce, ty, impl_items) => {
let new_impl_items = impl_items.into_iter()
.map(|item| folder.fold_impl_item(item))
.collect();
let new_impl_items = impl_items
.move_map(|item| folder.fold_impl_item(item));
let ifce = match ifce {
None => None,
Some(ref trait_ref) => {
Expand All @@ -834,9 +808,7 @@ pub fn noop_fold_item_underscore<T: Folder>(i: Item_, folder: &mut T) -> Item_ {
}
ItemTrait(unsafety, generics, bounds, items) => {
let bounds = folder.fold_bounds(bounds);
let items = items.into_iter()
.map(|item| folder.fold_trait_item(item))
.collect();
let items = items.move_map(|item| folder.fold_trait_item(item));
ItemTrait(unsafety, folder.fold_generics(generics), bounds, items)
}
}
Expand Down Expand Up @@ -892,7 +864,7 @@ pub fn noop_fold_impl_item<T: Folder>(i: P<ImplItem>, folder: &mut T) -> P<ImplI
pub fn noop_fold_mod<T: Folder>(Mod { inner, item_ids }: Mod, folder: &mut T) -> Mod {
Mod {
inner: folder.new_span(inner),
item_ids: item_ids.into_iter().map(|x| folder.fold_item_id(x)).collect(),
item_ids: item_ids.move_map(|x| folder.fold_item_id(x)),
}
}

Expand Down Expand Up @@ -1048,7 +1020,7 @@ pub fn noop_fold_pat<T: Folder>(p: P<Pat>, folder: &mut T) -> P<Pat> {
})
}

pub fn noop_fold_expr<T: Folder>(Expr { id, node, span }: Expr, folder: &mut T) -> Expr {
pub fn noop_fold_expr<T: Folder>(Expr { id, node, span, attrs }: Expr, folder: &mut T) -> Expr {
Expr {
id: folder.new_id(id),
node: match node {
Expand Down Expand Up @@ -1171,6 +1143,7 @@ pub fn noop_fold_expr<T: Folder>(Expr { id, node, span }: Expr, folder: &mut T)
}
},
span: folder.new_span(span),
attrs: attrs.map_thin_attrs(|attrs| fold_attrs(attrs, folder)),
}
}

Expand Down
3 changes: 3 additions & 0 deletions src/librustc_front/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ use syntax::codemap::{self, Span, Spanned, DUMMY_SP, ExpnId};
use syntax::abi::Abi;
use syntax::ast::{Name, Ident, NodeId, DUMMY_NODE_ID, TokenTree, AsmDialect};
use syntax::ast::{Attribute, Lit, StrStyle, FloatTy, IntTy, UintTy, CrateConfig};
use syntax::attr::ThinAttributes;
use syntax::owned_slice::OwnedSlice;
use syntax::parse::token::InternedString;
use syntax::ptr::P;
Expand Down Expand Up @@ -558,6 +559,7 @@ pub struct Local {
pub init: Option<P<Expr>>,
pub id: NodeId,
pub span: Span,
pub attrs: ThinAttributes,
}

pub type Decl = Spanned<Decl_>;
Expand Down Expand Up @@ -609,6 +611,7 @@ pub struct Expr {
pub id: NodeId,
pub node: Expr_,
pub span: Span,
pub attrs: ThinAttributes,
}

impl fmt::Debug for Expr {
Expand Down
1 change: 0 additions & 1 deletion src/librustc_front/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
#![feature(slice_patterns)]
#![feature(staged_api)]
#![feature(str_char)]
#![feature(filling_drop)]

extern crate serialize;
#[macro_use]
Expand Down
Loading