Skip to content

Commit a4cd2ec

Browse files
authored
Rollup merge of rust-lang#61856 - c410-f3r:attrs-fn, r=matthewjasper
Lint attributes on function arguments Fixes rust-lang#61238. cc rust-lang#60406
2 parents 023525d + 53fc7fb commit a4cd2ec

28 files changed

+586
-292
lines changed

src/librustc/hir/intravisit.rs

+11-4
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,10 @@ pub trait Visitor<'v> : Sized {
210210
}
211211
}
212212

213+
fn visit_arg(&mut self, arg: &'v Arg) {
214+
walk_arg(self, arg)
215+
}
216+
213217
/// Visits the top-level item and (optionally) nested items / impl items. See
214218
/// `visit_nested_item` for details.
215219
fn visit_item(&mut self, i: &'v Item) {
@@ -396,10 +400,7 @@ pub fn walk_mod<'v, V: Visitor<'v>>(visitor: &mut V, module: &'v Mod, mod_hir_id
396400
}
397401

398402
pub fn walk_body<'v, V: Visitor<'v>>(visitor: &mut V, body: &'v Body) {
399-
for argument in &body.arguments {
400-
visitor.visit_id(argument.hir_id);
401-
visitor.visit_pat(&argument.pat);
402-
}
403+
walk_list!(visitor, visit_arg, &body.arguments);
403404
visitor.visit_expr(&body.value);
404405
}
405406

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

456+
pub fn walk_arg<'v, V: Visitor<'v>>(visitor: &mut V, arg: &'v Arg) {
457+
visitor.visit_id(arg.hir_id);
458+
visitor.visit_pat(&arg.pat);
459+
walk_list!(visitor, visit_attribute, &arg.attrs);
460+
}
461+
455462
pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
456463
visitor.visit_vis(&item.vis);
457464
visitor.visit_ident(item.ident);

src/librustc/hir/lowering.rs

+34-9
Original file line numberDiff line numberDiff line change
@@ -2461,8 +2461,10 @@ impl<'a> LoweringContext<'a> {
24612461

24622462
fn lower_arg(&mut self, arg: &Arg) -> hir::Arg {
24632463
hir::Arg {
2464+
attrs: self.lower_attrs(&arg.attrs),
24642465
hir_id: self.lower_node_id(arg.id),
24652466
pat: self.lower_pat(&arg.pat),
2467+
span: arg.span,
24662468
}
24672469
}
24682470

@@ -3279,19 +3281,29 @@ impl<'a> LoweringContext<'a> {
32793281
//
32803282
// If this is the simple case, this argument will end up being the same as the
32813283
// original argument, but with a different pattern id.
3284+
let mut stmt_attrs = ThinVec::new();
3285+
stmt_attrs.extend(argument.attrs.iter().cloned());
32823286
let (new_argument_pat, new_argument_id) = this.pat_ident(desugared_span, ident);
32833287
let new_argument = hir::Arg {
3288+
attrs: argument.attrs,
32843289
hir_id: argument.hir_id,
32853290
pat: new_argument_pat,
3291+
span: argument.span,
32863292
};
32873293

3294+
32883295
if is_simple_argument {
32893296
// If this is the simple case, then we only insert one statement that is
32903297
// `let <pat> = <pat>;`. We re-use the original argument's pattern so that
32913298
// `HirId`s are densely assigned.
32923299
let expr = this.expr_ident(desugared_span, ident, new_argument_id);
32933300
let stmt = this.stmt_let_pat(
3294-
desugared_span, Some(P(expr)), argument.pat, hir::LocalSource::AsyncFn);
3301+
stmt_attrs,
3302+
desugared_span,
3303+
Some(P(expr)),
3304+
argument.pat,
3305+
hir::LocalSource::AsyncFn
3306+
);
32953307
statements.push(stmt);
32963308
} else {
32973309
// If this is not the simple case, then we construct two statements:
@@ -3313,14 +3325,23 @@ impl<'a> LoweringContext<'a> {
33133325
desugared_span, ident, hir::BindingAnnotation::Mutable);
33143326
let move_expr = this.expr_ident(desugared_span, ident, new_argument_id);
33153327
let move_stmt = this.stmt_let_pat(
3316-
desugared_span, Some(P(move_expr)), move_pat, hir::LocalSource::AsyncFn);
3328+
ThinVec::new(),
3329+
desugared_span,
3330+
Some(P(move_expr)),
3331+
move_pat,
3332+
hir::LocalSource::AsyncFn
3333+
);
33173334

33183335
// Construct the `let <pat> = __argN;` statement. We re-use the original
33193336
// argument's pattern so that `HirId`s are densely assigned.
33203337
let pattern_expr = this.expr_ident(desugared_span, ident, move_id);
33213338
let pattern_stmt = this.stmt_let_pat(
3322-
desugared_span, Some(P(pattern_expr)), argument.pat,
3323-
hir::LocalSource::AsyncFn);
3339+
stmt_attrs,
3340+
desugared_span,
3341+
Some(P(pattern_expr)),
3342+
argument.pat,
3343+
hir::LocalSource::AsyncFn
3344+
);
33243345

33253346
statements.push(move_stmt);
33263347
statements.push(pattern_stmt);
@@ -5030,6 +5051,7 @@ impl<'a> LoweringContext<'a> {
50305051

50315052
// `let mut __next`
50325053
let next_let = self.stmt_let_pat(
5054+
ThinVec::new(),
50335055
desugared_span,
50345056
None,
50355057
next_pat,
@@ -5039,6 +5061,7 @@ impl<'a> LoweringContext<'a> {
50395061
// `let <pat> = __next`
50405062
let pat = self.lower_pat(pat);
50415063
let pat_let = self.stmt_let_pat(
5064+
ThinVec::new(),
50425065
head_sp,
50435066
Some(next_expr),
50445067
pat,
@@ -5533,19 +5556,20 @@ impl<'a> LoweringContext<'a> {
55335556

55345557
fn stmt_let_pat(
55355558
&mut self,
5559+
attrs: ThinVec<Attribute>,
55365560
span: Span,
55375561
init: Option<P<hir::Expr>>,
55385562
pat: P<hir::Pat>,
55395563
source: hir::LocalSource,
55405564
) -> hir::Stmt {
55415565
let local = hir::Local {
5542-
pat,
5543-
ty: None,
5544-
init,
5566+
attrs,
55455567
hir_id: self.next_id(),
5546-
span,
5568+
init,
5569+
pat,
55475570
source,
5548-
attrs: ThinVec::new()
5571+
span,
5572+
ty: None,
55495573
};
55505574
self.stmt(span, hir::StmtKind::Local(P(local)))
55515575
}
@@ -5959,6 +5983,7 @@ impl<'a> LoweringContext<'a> {
59595983
hir::BindingAnnotation::Mutable,
59605984
);
59615985
let pinned_let = self.stmt_let_pat(
5986+
ThinVec::new(),
59625987
span,
59635988
Some(expr),
59645989
pinned_pat,

src/librustc/hir/map/collector.rs

+8
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,14 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
363363
self.currently_in_body = prev_in_body;
364364
}
365365

366+
fn visit_arg(&mut self, arg: &'hir Arg) {
367+
let node = Node::Arg(arg);
368+
self.insert(arg.pat.span, arg.hir_id, node);
369+
self.with_parent(arg.hir_id, |this| {
370+
intravisit::walk_arg(this, arg);
371+
});
372+
}
373+
366374
fn visit_item(&mut self, i: &'hir Item) {
367375
debug!("visit_item: {:?}", i);
368376
debug_assert_eq!(i.hir_id.owner,

src/librustc/hir/map/mod.rs

+7
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,7 @@ impl<'hir> Map<'hir> {
360360
Node::Pat(_) |
361361
Node::Binding(_) |
362362
Node::Local(_) |
363+
Node::Arg(_) |
363364
Node::Arm(_) |
364365
Node::Lifetime(_) |
365366
Node::Visibility(_) |
@@ -932,6 +933,7 @@ impl<'hir> Map<'hir> {
932933
pub fn attrs(&self, id: HirId) -> &'hir [ast::Attribute] {
933934
self.read(id); // reveals attributes on the node
934935
let attrs = match self.find_entry(id).map(|entry| entry.node) {
936+
Some(Node::Arg(a)) => Some(&a.attrs[..]),
935937
Some(Node::Local(l)) => Some(&l.attrs[..]),
936938
Some(Node::Item(i)) => Some(&i.attrs[..]),
937939
Some(Node::ForeignItem(fi)) => Some(&fi.attrs[..]),
@@ -995,6 +997,7 @@ impl<'hir> Map<'hir> {
995997
pub fn span(&self, hir_id: HirId) -> Span {
996998
self.read(hir_id); // reveals span from node
997999
match self.find_entry(hir_id).map(|entry| entry.node) {
1000+
Some(Node::Arg(arg)) => arg.span,
9981001
Some(Node::Item(item)) => item.span,
9991002
Some(Node::ForeignItem(foreign_item)) => foreign_item.span,
10001003
Some(Node::TraitItem(trait_method)) => trait_method.span,
@@ -1197,6 +1200,7 @@ impl<'hir> print::PpAnn for Map<'hir> {
11971200
impl<'a> print::State<'a> {
11981201
pub fn print_node(&mut self, node: Node<'_>) {
11991202
match node {
1203+
Node::Arg(a) => self.print_arg(&a),
12001204
Node::Item(a) => self.print_item(&a),
12011205
Node::ForeignItem(a) => self.print_foreign_item(&a),
12021206
Node::TraitItem(a) => self.print_trait_item(a),
@@ -1338,6 +1342,9 @@ fn hir_id_to_string(map: &Map<'_>, id: HirId, include_id: bool) -> String {
13381342
Some(Node::Pat(_)) => {
13391343
format!("pat {}{}", map.hir_to_pretty_string(id), id_str)
13401344
}
1345+
Some(Node::Arg(_)) => {
1346+
format!("arg {}{}", map.hir_to_pretty_string(id), id_str)
1347+
}
13411348
Some(Node::Arm(_)) => {
13421349
format!("arm {}{}", map.hir_to_pretty_string(id), id_str)
13431350
}

src/librustc/hir/mod.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -2010,8 +2010,10 @@ pub struct InlineAsm {
20102010
/// Represents an argument in a function header.
20112011
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
20122012
pub struct Arg {
2013-
pub pat: P<Pat>,
2013+
pub attrs: HirVec<Attribute>,
20142014
pub hir_id: HirId,
2015+
pub pat: P<Pat>,
2016+
pub span: Span,
20152017
}
20162018

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

27022704
#[derive(Copy, Clone, Debug)]
27032705
pub enum Node<'hir> {
2706+
Arg(&'hir Arg),
27042707
Item(&'hir Item),
27052708
ForeignItem(&'hir ForeignItem),
27062709
TraitItem(&'hir TraitItem),

src/librustc/hir/print.rs

+5
Original file line numberDiff line numberDiff line change
@@ -1767,6 +1767,11 @@ impl<'a> State<'a> {
17671767
self.ann.post(self, AnnNode::Pat(pat))
17681768
}
17691769

1770+
pub fn print_arg(&mut self, arg: &hir::Arg) {
1771+
self.print_outer_attributes(&arg.attrs);
1772+
self.print_pat(&arg.pat);
1773+
}
1774+
17701775
pub fn print_arm(&mut self, arm: &hir::Arm) {
17711776
// I have no idea why this check is necessary, but here it
17721777
// is :(

src/librustc/lint/context.rs

+14
Original file line numberDiff line numberDiff line change
@@ -966,6 +966,13 @@ for LateContextAndPass<'a, 'tcx, T> {
966966
self.context.tables = old_tables;
967967
}
968968

969+
fn visit_arg(&mut self, arg: &'tcx hir::Arg) {
970+
self.with_lint_attrs(arg.hir_id, &arg.attrs, |cx| {
971+
lint_callback!(cx, check_arg, arg);
972+
hir_visit::walk_arg(cx, arg);
973+
});
974+
}
975+
969976
fn visit_body(&mut self, body: &'tcx hir::Body) {
970977
lint_callback!(self, check_body, body);
971978
hir_visit::walk_body(self, body);
@@ -1156,6 +1163,13 @@ for LateContextAndPass<'a, 'tcx, T> {
11561163
}
11571164

11581165
impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> {
1166+
fn visit_arg(&mut self, arg: &'a ast::Arg) {
1167+
self.with_lint_attrs(arg.id, &arg.attrs, |cx| {
1168+
run_early_pass!(cx, check_arg, arg);
1169+
ast_visit::walk_arg(cx, arg);
1170+
});
1171+
}
1172+
11591173
fn visit_item(&mut self, it: &'a ast::Item) {
11601174
self.with_lint_attrs(it.id, &it.attrs, |cx| {
11611175
run_early_pass!(cx, check_item, it);

src/librustc/lint/mod.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ macro_rules! declare_lint_pass {
206206
macro_rules! late_lint_methods {
207207
($macro:path, $args:tt, [$hir:tt]) => (
208208
$macro!($args, [$hir], [
209+
fn check_arg(a: &$hir hir::Arg);
209210
fn check_body(a: &$hir hir::Body);
210211
fn check_body_post(a: &$hir hir::Body);
211212
fn check_name(a: Span, b: ast::Name);
@@ -358,6 +359,7 @@ macro_rules! declare_combined_late_lint_pass {
358359
macro_rules! early_lint_methods {
359360
($macro:path, $args:tt) => (
360361
$macro!($args, [
362+
fn check_arg(a: &ast::Arg);
361363
fn check_ident(a: ast::Ident);
362364
fn check_crate(a: &ast::Crate);
363365
fn check_crate_post(a: &ast::Crate);
@@ -495,8 +497,6 @@ pub type EarlyLintPassObject = Box<dyn EarlyLintPass + sync::Send + sync::Sync +
495497
pub type LateLintPassObject = Box<dyn for<'a, 'tcx> LateLintPass<'a, 'tcx> + sync::Send
496498
+ sync::Sync + 'static>;
497499

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

815+
fn visit_arg(&mut self, arg: &'tcx hir::Arg) {
816+
self.with_lint_attrs(arg.hir_id, &arg.attrs, |builder| {
817+
intravisit::walk_arg(builder, arg);
818+
});
819+
}
820+
815821
fn visit_item(&mut self, it: &'tcx hir::Item) {
816822
self.with_lint_attrs(it.hir_id, &it.attrs, |builder| {
817823
intravisit::walk_item(builder, it);

0 commit comments

Comments
 (0)