Skip to content

Commit

Permalink
Add syntax support for attributes on expressions and all syntax
Browse files Browse the repository at this point in the history
nodes in statement position.

Extended #[cfg] folder to allow removal of statements, and
of expressions in optional positions like expression lists and trailing
block expressions.

Extended lint checker to recognize lint levels on expressions and
locals.
  • Loading branch information
Kimundi committed Nov 26, 2015
1 parent 6ef02ef commit 2a8f358
Show file tree
Hide file tree
Showing 34 changed files with 1,602 additions and 416 deletions.
19 changes: 14 additions & 5 deletions src/librustc/lint/context.rs
Expand Up @@ -41,7 +41,7 @@ use syntax::ast_util::{self, IdVisitingOperation};
use syntax::attr::{self, AttrMetaMethods};
use syntax::codemap::Span;
use syntax::parse::token::InternedString;
use syntax::ast;
use syntax::ast::{self, ThinAttributesExt};
use rustc_front::hir;
use rustc_front::util;
use rustc_front::intravisit as hir_visit;
Expand Down Expand Up @@ -674,11 +674,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_attrs(), |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 +737,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_attrs(), |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
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
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
8 changes: 5 additions & 3 deletions src/librustc_front/fold.rs
Expand Up @@ -13,7 +13,7 @@

use hir::*;
use syntax::ast::{Ident, Name, NodeId, DUMMY_NODE_ID, Attribute, Attribute_, MetaItem};
use syntax::ast::{MetaWord, MetaList, MetaNameValue};
use syntax::ast::{MetaWord, MetaList, MetaNameValue, ThinAttributesExt};
use hir;
use syntax::codemap::{respan, Span, Spanned};
use syntax::owned_slice::OwnedSlice;
Expand Down Expand Up @@ -501,13 +501,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_opt_attrs(|attrs| fold_attrs(attrs, fld)),
}
})
}
Expand Down Expand Up @@ -1048,7 +1049,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 +1172,7 @@ pub fn noop_fold_expr<T: Folder>(Expr { id, node, span }: Expr, folder: &mut T)
}
},
span: folder.new_span(span),
attrs: attrs.map_opt_attrs(|attrs| fold_attrs(attrs, folder)),
}
}

Expand Down
3 changes: 3 additions & 0 deletions src/librustc_front/hir.rs
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::ast::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
65 changes: 44 additions & 21 deletions src/librustc_front/lowering.rs
Expand Up @@ -331,6 +331,7 @@ pub fn lower_local(lctx: &LoweringContext, l: &Local) -> P<hir::Local> {
pat: lower_pat(lctx, &l.pat),
init: l.init.as_ref().map(|e| lower_expr(lctx, e)),
span: l.span,
attrs: l.attrs.clone(),
})
}

Expand Down Expand Up @@ -1215,7 +1216,14 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
maybe_expr.as_ref().map(|x| lower_expr(lctx, x)))
}
ExprParen(ref ex) => {
return lower_expr(lctx, ex);
// merge attributes into the inner expression.
return lower_expr(lctx, ex).map(|mut ex| {
ex.attrs.update(|attrs| {
// FIXME: Badly named
attrs.prepend_outer(e.attrs.clone())
});
ex
});
}

// Desugar ExprIfLet
Expand Down Expand Up @@ -1454,6 +1462,7 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
ExprMac(_) => panic!("Shouldn't exist here"),
},
span: e.span,
attrs: e.attrs.clone(),
})
}

Expand Down Expand Up @@ -1552,60 +1561,71 @@ fn arm(pats: Vec<P<hir::Pat>>, expr: P<hir::Expr>) -> hir::Arm {
}
}

fn expr_break(lctx: &LoweringContext, span: Span) -> P<hir::Expr> {
expr(lctx, span, hir::ExprBreak(None))
fn expr_break(lctx: &LoweringContext, span: Span,
attrs: ThinAttributes) -> P<hir::Expr> {
expr(lctx, span, hir::ExprBreak(None), attrs)
}

fn expr_call(lctx: &LoweringContext,
span: Span,
e: P<hir::Expr>,
args: Vec<P<hir::Expr>>)
args: Vec<P<hir::Expr>>,
attrs: ThinAttributes)
-> P<hir::Expr> {
expr(lctx, span, hir::ExprCall(e, args))
expr(lctx, span, hir::ExprCall(e, args), attrs)
}

fn expr_ident(lctx: &LoweringContext, span: Span, id: Ident) -> P<hir::Expr> {
expr_path(lctx, path_ident(span, id))
fn expr_ident(lctx: &LoweringContext, span: Span, id: Ident,
attrs: ThinAttributes) -> P<hir::Expr> {
expr_path(lctx, path_ident(span, id), attrs)
}

fn expr_mut_addr_of(lctx: &LoweringContext, span: Span, e: P<hir::Expr>) -> P<hir::Expr> {
expr(lctx, span, hir::ExprAddrOf(hir::MutMutable, e))
fn expr_mut_addr_of(lctx: &LoweringContext, span: Span, e: P<hir::Expr>,
attrs: ThinAttributes) -> P<hir::Expr> {
expr(lctx, span, hir::ExprAddrOf(hir::MutMutable, e), attrs)
}

fn expr_path(lctx: &LoweringContext, path: hir::Path) -> P<hir::Expr> {
expr(lctx, path.span, hir::ExprPath(None, path))
fn expr_path(lctx: &LoweringContext, path: hir::Path,
attrs: ThinAttributes) -> P<hir::Expr> {
expr(lctx, path.span, hir::ExprPath(None, path), attrs)
}

fn expr_match(lctx: &LoweringContext,
span: Span,
arg: P<hir::Expr>,
arms: Vec<hir::Arm>,
source: hir::MatchSource)
source: hir::MatchSource,
attrs: ThinAttributes)
-> P<hir::Expr> {
expr(lctx, span, hir::ExprMatch(arg, arms, source))
expr(lctx, span, hir::ExprMatch(arg, arms, source), attrs)
}

fn expr_block(lctx: &LoweringContext, b: P<hir::Block>) -> P<hir::Expr> {
expr(lctx, b.span, hir::ExprBlock(b))
fn expr_block(lctx: &LoweringContext, b: P<hir::Block>,
attrs: ThinAttributes) -> P<hir::Expr> {
expr(lctx, b.span, hir::ExprBlock(b), attrs)
}

fn expr_tuple(lctx: &LoweringContext, sp: Span, exprs: Vec<P<hir::Expr>>) -> P<hir::Expr> {
expr(lctx, sp, hir::ExprTup(exprs))
fn expr_tuple(lctx: &LoweringContext, sp: Span, exprs: Vec<P<hir::Expr>>,
attrs: ThinAttributes) -> P<hir::Expr> {
expr(lctx, sp, hir::ExprTup(exprs), attrs)
}

fn expr(lctx: &LoweringContext, span: Span, node: hir::Expr_) -> P<hir::Expr> {
fn expr(lctx: &LoweringContext, span: Span, node: hir::Expr_,
attrs: ThinAttributes) -> P<hir::Expr> {
P(hir::Expr {
id: lctx.next_id(),
node: node,
span: span,
attrs: attrs,
})
}

fn stmt_let(lctx: &LoweringContext,
sp: Span,
mutbl: bool,
ident: Ident,
ex: P<hir::Expr>)
ex: P<hir::Expr>,
attrs: ThinAttributes)
-> P<hir::Stmt> {
let pat = if mutbl {
pat_ident_binding_mode(lctx, sp, ident, hir::BindByValue(hir::MutMutable))
Expand All @@ -1618,6 +1638,7 @@ fn stmt_let(lctx: &LoweringContext,
init: Some(ex),
id: lctx.next_id(),
span: sp,
attrs: attrs,
});
let decl = respan(sp, hir::DeclLocal(local));
P(respan(sp, hir::StmtDecl(P(decl), lctx.next_id())))
Expand Down Expand Up @@ -1755,7 +1776,8 @@ fn signal_block_expr(lctx: &LoweringContext,
stmts: Vec<P<hir::Stmt>>,
expr: P<hir::Expr>,
span: Span,
rule: hir::BlockCheckMode)
rule: hir::BlockCheckMode,
attrs: ThinAttributes)
-> P<hir::Expr> {
let id = lctx.next_id();
expr_block(lctx,
Expand All @@ -1765,7 +1787,8 @@ fn signal_block_expr(lctx: &LoweringContext,
id: id,
stmts: stmts,
expr: Some(expr),
}))
}),
attrs)
}


Expand Down
2 changes: 1 addition & 1 deletion src/librustc_lint/bad_style.rs
Expand Up @@ -138,7 +138,7 @@ impl LateLintPass for NonCamelCaseTypes {
declare_lint! {
pub NON_SNAKE_CASE,
Warn,
"methods, functions, lifetime parameters and modules should have snake case names"
"variables, methods, functions, lifetime parameters and modules should have snake case names"
}

#[derive(Copy, Clone)]
Expand Down

0 comments on commit 2a8f358

Please sign in to comment.