Skip to content

Commit

Permalink
Rollup merge of rust-lang#61856 - c410-f3r:attrs-fn, r=matthewjasper
Browse files Browse the repository at this point in the history
Lint attributes on function arguments

Fixes rust-lang#61238.

cc rust-lang#60406
  • Loading branch information
Centril committed Jul 28, 2019
2 parents 023525d + 53fc7fb commit a4cd2ec
Show file tree
Hide file tree
Showing 28 changed files with 586 additions and 292 deletions.
15 changes: 11 additions & 4 deletions src/librustc/hir/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,10 @@ pub trait Visitor<'v> : Sized {
}
}

fn visit_arg(&mut self, arg: &'v Arg) {
walk_arg(self, arg)
}

/// Visits the top-level item and (optionally) nested items / impl items. See
/// `visit_nested_item` for details.
fn visit_item(&mut self, i: &'v Item) {
Expand Down Expand Up @@ -396,10 +400,7 @@ pub fn walk_mod<'v, V: Visitor<'v>>(visitor: &mut V, module: &'v Mod, mod_hir_id
}

pub fn walk_body<'v, V: Visitor<'v>>(visitor: &mut V, body: &'v Body) {
for argument in &body.arguments {
visitor.visit_id(argument.hir_id);
visitor.visit_pat(&argument.pat);
}
walk_list!(visitor, visit_arg, &body.arguments);
visitor.visit_expr(&body.value);
}

Expand Down Expand Up @@ -452,6 +453,12 @@ pub fn walk_trait_ref<'v, V>(visitor: &mut V, trait_ref: &'v TraitRef)
visitor.visit_path(&trait_ref.path, trait_ref.hir_ref_id)
}

pub fn walk_arg<'v, V: Visitor<'v>>(visitor: &mut V, arg: &'v Arg) {
visitor.visit_id(arg.hir_id);
visitor.visit_pat(&arg.pat);
walk_list!(visitor, visit_attribute, &arg.attrs);
}

pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
visitor.visit_vis(&item.vis);
visitor.visit_ident(item.ident);
Expand Down
43 changes: 34 additions & 9 deletions src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2461,8 +2461,10 @@ impl<'a> LoweringContext<'a> {

fn lower_arg(&mut self, arg: &Arg) -> hir::Arg {
hir::Arg {
attrs: self.lower_attrs(&arg.attrs),
hir_id: self.lower_node_id(arg.id),
pat: self.lower_pat(&arg.pat),
span: arg.span,
}
}

Expand Down Expand Up @@ -3279,19 +3281,29 @@ impl<'a> LoweringContext<'a> {
//
// If this is the simple case, this argument will end up being the same as the
// original argument, but with a different pattern id.
let mut stmt_attrs = ThinVec::new();
stmt_attrs.extend(argument.attrs.iter().cloned());
let (new_argument_pat, new_argument_id) = this.pat_ident(desugared_span, ident);
let new_argument = hir::Arg {
attrs: argument.attrs,
hir_id: argument.hir_id,
pat: new_argument_pat,
span: argument.span,
};


if is_simple_argument {
// If this is the simple case, then we only insert one statement that is
// `let <pat> = <pat>;`. We re-use the original argument's pattern so that
// `HirId`s are densely assigned.
let expr = this.expr_ident(desugared_span, ident, new_argument_id);
let stmt = this.stmt_let_pat(
desugared_span, Some(P(expr)), argument.pat, hir::LocalSource::AsyncFn);
stmt_attrs,
desugared_span,
Some(P(expr)),
argument.pat,
hir::LocalSource::AsyncFn
);
statements.push(stmt);
} else {
// If this is not the simple case, then we construct two statements:
Expand All @@ -3313,14 +3325,23 @@ impl<'a> LoweringContext<'a> {
desugared_span, ident, hir::BindingAnnotation::Mutable);
let move_expr = this.expr_ident(desugared_span, ident, new_argument_id);
let move_stmt = this.stmt_let_pat(
desugared_span, Some(P(move_expr)), move_pat, hir::LocalSource::AsyncFn);
ThinVec::new(),
desugared_span,
Some(P(move_expr)),
move_pat,
hir::LocalSource::AsyncFn
);

// Construct the `let <pat> = __argN;` statement. We re-use the original
// argument's pattern so that `HirId`s are densely assigned.
let pattern_expr = this.expr_ident(desugared_span, ident, move_id);
let pattern_stmt = this.stmt_let_pat(
desugared_span, Some(P(pattern_expr)), argument.pat,
hir::LocalSource::AsyncFn);
stmt_attrs,
desugared_span,
Some(P(pattern_expr)),
argument.pat,
hir::LocalSource::AsyncFn
);

statements.push(move_stmt);
statements.push(pattern_stmt);
Expand Down Expand Up @@ -5030,6 +5051,7 @@ impl<'a> LoweringContext<'a> {

// `let mut __next`
let next_let = self.stmt_let_pat(
ThinVec::new(),
desugared_span,
None,
next_pat,
Expand All @@ -5039,6 +5061,7 @@ impl<'a> LoweringContext<'a> {
// `let <pat> = __next`
let pat = self.lower_pat(pat);
let pat_let = self.stmt_let_pat(
ThinVec::new(),
head_sp,
Some(next_expr),
pat,
Expand Down Expand Up @@ -5533,19 +5556,20 @@ impl<'a> LoweringContext<'a> {

fn stmt_let_pat(
&mut self,
attrs: ThinVec<Attribute>,
span: Span,
init: Option<P<hir::Expr>>,
pat: P<hir::Pat>,
source: hir::LocalSource,
) -> hir::Stmt {
let local = hir::Local {
pat,
ty: None,
init,
attrs,
hir_id: self.next_id(),
span,
init,
pat,
source,
attrs: ThinVec::new()
span,
ty: None,
};
self.stmt(span, hir::StmtKind::Local(P(local)))
}
Expand Down Expand Up @@ -5959,6 +5983,7 @@ impl<'a> LoweringContext<'a> {
hir::BindingAnnotation::Mutable,
);
let pinned_let = self.stmt_let_pat(
ThinVec::new(),
span,
Some(expr),
pinned_pat,
Expand Down
8 changes: 8 additions & 0 deletions src/librustc/hir/map/collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,14 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
self.currently_in_body = prev_in_body;
}

fn visit_arg(&mut self, arg: &'hir Arg) {
let node = Node::Arg(arg);
self.insert(arg.pat.span, arg.hir_id, node);
self.with_parent(arg.hir_id, |this| {
intravisit::walk_arg(this, arg);
});
}

fn visit_item(&mut self, i: &'hir Item) {
debug!("visit_item: {:?}", i);
debug_assert_eq!(i.hir_id.owner,
Expand Down
7 changes: 7 additions & 0 deletions src/librustc/hir/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,7 @@ impl<'hir> Map<'hir> {
Node::Pat(_) |
Node::Binding(_) |
Node::Local(_) |
Node::Arg(_) |
Node::Arm(_) |
Node::Lifetime(_) |
Node::Visibility(_) |
Expand Down Expand Up @@ -932,6 +933,7 @@ impl<'hir> Map<'hir> {
pub fn attrs(&self, id: HirId) -> &'hir [ast::Attribute] {
self.read(id); // reveals attributes on the node
let attrs = match self.find_entry(id).map(|entry| entry.node) {
Some(Node::Arg(a)) => Some(&a.attrs[..]),
Some(Node::Local(l)) => Some(&l.attrs[..]),
Some(Node::Item(i)) => Some(&i.attrs[..]),
Some(Node::ForeignItem(fi)) => Some(&fi.attrs[..]),
Expand Down Expand Up @@ -995,6 +997,7 @@ impl<'hir> Map<'hir> {
pub fn span(&self, hir_id: HirId) -> Span {
self.read(hir_id); // reveals span from node
match self.find_entry(hir_id).map(|entry| entry.node) {
Some(Node::Arg(arg)) => arg.span,
Some(Node::Item(item)) => item.span,
Some(Node::ForeignItem(foreign_item)) => foreign_item.span,
Some(Node::TraitItem(trait_method)) => trait_method.span,
Expand Down Expand Up @@ -1197,6 +1200,7 @@ impl<'hir> print::PpAnn for Map<'hir> {
impl<'a> print::State<'a> {
pub fn print_node(&mut self, node: Node<'_>) {
match node {
Node::Arg(a) => self.print_arg(&a),
Node::Item(a) => self.print_item(&a),
Node::ForeignItem(a) => self.print_foreign_item(&a),
Node::TraitItem(a) => self.print_trait_item(a),
Expand Down Expand Up @@ -1338,6 +1342,9 @@ fn hir_id_to_string(map: &Map<'_>, id: HirId, include_id: bool) -> String {
Some(Node::Pat(_)) => {
format!("pat {}{}", map.hir_to_pretty_string(id), id_str)
}
Some(Node::Arg(_)) => {
format!("arg {}{}", map.hir_to_pretty_string(id), id_str)
}
Some(Node::Arm(_)) => {
format!("arm {}{}", map.hir_to_pretty_string(id), id_str)
}
Expand Down
5 changes: 4 additions & 1 deletion src/librustc/hir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2010,8 +2010,10 @@ pub struct InlineAsm {
/// Represents an argument in a function header.
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct Arg {
pub pat: P<Pat>,
pub attrs: HirVec<Attribute>,
pub hir_id: HirId,
pub pat: P<Pat>,
pub span: Span,
}

/// Represents the header (not the body) of a function declaration.
Expand Down Expand Up @@ -2701,6 +2703,7 @@ impl CodegenFnAttrs {

#[derive(Copy, Clone, Debug)]
pub enum Node<'hir> {
Arg(&'hir Arg),
Item(&'hir Item),
ForeignItem(&'hir ForeignItem),
TraitItem(&'hir TraitItem),
Expand Down
5 changes: 5 additions & 0 deletions src/librustc/hir/print.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1767,6 +1767,11 @@ impl<'a> State<'a> {
self.ann.post(self, AnnNode::Pat(pat))
}

pub fn print_arg(&mut self, arg: &hir::Arg) {
self.print_outer_attributes(&arg.attrs);
self.print_pat(&arg.pat);
}

pub fn print_arm(&mut self, arm: &hir::Arm) {
// I have no idea why this check is necessary, but here it
// is :(
Expand Down
14 changes: 14 additions & 0 deletions src/librustc/lint/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -966,6 +966,13 @@ for LateContextAndPass<'a, 'tcx, T> {
self.context.tables = old_tables;
}

fn visit_arg(&mut self, arg: &'tcx hir::Arg) {
self.with_lint_attrs(arg.hir_id, &arg.attrs, |cx| {
lint_callback!(cx, check_arg, arg);
hir_visit::walk_arg(cx, arg);
});
}

fn visit_body(&mut self, body: &'tcx hir::Body) {
lint_callback!(self, check_body, body);
hir_visit::walk_body(self, body);
Expand Down Expand Up @@ -1156,6 +1163,13 @@ for LateContextAndPass<'a, 'tcx, T> {
}

impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> {
fn visit_arg(&mut self, arg: &'a ast::Arg) {
self.with_lint_attrs(arg.id, &arg.attrs, |cx| {
run_early_pass!(cx, check_arg, arg);
ast_visit::walk_arg(cx, arg);
});
}

fn visit_item(&mut self, it: &'a ast::Item) {
self.with_lint_attrs(it.id, &it.attrs, |cx| {
run_early_pass!(cx, check_item, it);
Expand Down
10 changes: 8 additions & 2 deletions src/librustc/lint/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ macro_rules! declare_lint_pass {
macro_rules! late_lint_methods {
($macro:path, $args:tt, [$hir:tt]) => (
$macro!($args, [$hir], [
fn check_arg(a: &$hir hir::Arg);
fn check_body(a: &$hir hir::Body);
fn check_body_post(a: &$hir hir::Body);
fn check_name(a: Span, b: ast::Name);
Expand Down Expand Up @@ -358,6 +359,7 @@ macro_rules! declare_combined_late_lint_pass {
macro_rules! early_lint_methods {
($macro:path, $args:tt) => (
$macro!($args, [
fn check_arg(a: &ast::Arg);
fn check_ident(a: ast::Ident);
fn check_crate(a: &ast::Crate);
fn check_crate_post(a: &ast::Crate);
Expand Down Expand Up @@ -495,8 +497,6 @@ pub type EarlyLintPassObject = Box<dyn EarlyLintPass + sync::Send + sync::Sync +
pub type LateLintPassObject = Box<dyn for<'a, 'tcx> LateLintPass<'a, 'tcx> + sync::Send
+ sync::Sync + 'static>;



/// Identifies a lint known to the compiler.
#[derive(Clone, Copy, Debug)]
pub struct LintId {
Expand Down Expand Up @@ -812,6 +812,12 @@ impl intravisit::Visitor<'tcx> for LintLevelMapBuilder<'tcx> {
intravisit::NestedVisitorMap::All(&self.tcx.hir())
}

fn visit_arg(&mut self, arg: &'tcx hir::Arg) {
self.with_lint_attrs(arg.hir_id, &arg.attrs, |builder| {
intravisit::walk_arg(builder, arg);
});
}

fn visit_item(&mut self, it: &'tcx hir::Item) {
self.with_lint_attrs(it.hir_id, &it.attrs, |builder| {
intravisit::walk_item(builder, it);
Expand Down
Loading

0 comments on commit a4cd2ec

Please sign in to comment.