Skip to content

Commit 468bbb8

Browse files
committed
Introduce ArgSource for diagnostics.
This commit introduces an `ArgSource` enum that is lowered into the HIR so that diagnostics can correctly refer to the argument pattern's original name rather than the generated pattern.
1 parent ea93cb5 commit 468bbb8

File tree

12 files changed

+90
-21
lines changed

12 files changed

+90
-21
lines changed

src/librustc/hir/intravisit.rs

+10
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,9 @@ pub trait Visitor<'v> : Sized {
254254
fn visit_pat(&mut self, p: &'v Pat) {
255255
walk_pat(self, p)
256256
}
257+
fn visit_argument_source(&mut self, s: &'v ArgSource) {
258+
walk_argument_source(self, s)
259+
}
257260
fn visit_anon_const(&mut self, c: &'v AnonConst) {
258261
walk_anon_const(self, c)
259262
}
@@ -391,10 +394,17 @@ pub fn walk_body<'v, V: Visitor<'v>>(visitor: &mut V, body: &'v Body) {
391394
for argument in &body.arguments {
392395
visitor.visit_id(argument.hir_id);
393396
visitor.visit_pat(&argument.pat);
397+
visitor.visit_argument_source(&argument.source);
394398
}
395399
visitor.visit_expr(&body.value);
396400
}
397401

402+
pub fn walk_argument_source<'v, V: Visitor<'v>>(visitor: &mut V, source: &'v ArgSource) {
403+
if let ArgSource::AsyncFn(pat) = source {
404+
visitor.visit_pat(pat);
405+
}
406+
}
407+
398408
pub fn walk_local<'v, V: Visitor<'v>>(visitor: &mut V, local: &'v Local) {
399409
// Intentionally visiting the expr first - the initialization expr
400410
// dominates the local's definition.

src/librustc/hir/lowering.rs

+8
Original file line numberDiff line numberDiff line change
@@ -2048,6 +2048,14 @@ impl<'a> LoweringContext<'a> {
20482048
hir::Arg {
20492049
hir_id,
20502050
pat: self.lower_pat(&arg.pat),
2051+
source: self.lower_arg_source(&arg.source),
2052+
}
2053+
}
2054+
2055+
fn lower_arg_source(&mut self, source: &ArgSource) -> hir::ArgSource {
2056+
match source {
2057+
ArgSource::Normal => hir::ArgSource::Normal,
2058+
ArgSource::AsyncFn(pat) => hir::ArgSource::AsyncFn(self.lower_pat(pat)),
20512059
}
20522060
}
20532061

src/librustc/hir/mod.rs

+20
Original file line numberDiff line numberDiff line change
@@ -1882,6 +1882,26 @@ pub struct InlineAsm {
18821882
pub struct Arg {
18831883
pub pat: P<Pat>,
18841884
pub hir_id: HirId,
1885+
pub source: ArgSource,
1886+
}
1887+
1888+
impl Arg {
1889+
/// Returns the pattern representing the original binding for this argument.
1890+
pub fn original_pat(&self) -> &P<Pat> {
1891+
match &self.source {
1892+
ArgSource::Normal => &self.pat,
1893+
ArgSource::AsyncFn(pat) => &pat,
1894+
}
1895+
}
1896+
}
1897+
1898+
/// Represents the source of an argument in a function header.
1899+
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
1900+
pub enum ArgSource {
1901+
/// Argument as specified by the user.
1902+
Normal,
1903+
/// Generated argument from `async fn` lowering, contains the original binding pattern.
1904+
AsyncFn(P<Pat>),
18851905
}
18861906

18871907
/// Represents the header (not the body) of a function declaration.

src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs

+6-9
Original file line numberDiff line numberDiff line change
@@ -86,19 +86,16 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
8686
let sub_is_ret_type =
8787
self.is_return_type_anon(scope_def_id_sub, bregion_sub, ty_fndecl_sub);
8888

89-
let span_label_var1 = if let Some(simple_ident) = anon_arg_sup.pat.simple_ident() {
90-
format!(" from `{}`", simple_ident)
91-
} else {
92-
String::new()
89+
let span_label_var1 = match anon_arg_sup.original_pat().simple_ident() {
90+
Some(simple_ident) => format!(" from `{}`", simple_ident),
91+
None => String::new(),
9392
};
9493

95-
let span_label_var2 = if let Some(simple_ident) = anon_arg_sub.pat.simple_ident() {
96-
format!(" into `{}`", simple_ident)
97-
} else {
98-
String::new()
94+
let span_label_var2 = match anon_arg_sub.original_pat().simple_ident() {
95+
Some(simple_ident) => format!(" into `{}`", simple_ident),
96+
None => String::new(),
9997
};
10098

101-
10299
let (span_1, span_2, main_label, span_label) = match (sup_is_ret_type, sub_is_ret_type) {
103100
(None, None) => {
104101
let (main_label_1, span_label_1) = if ty_sup.hir_id == ty_sub.hir_id {

src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -86,13 +86,12 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
8686
}
8787
}
8888

89-
let (error_var, span_label_var) = if let Some(simple_ident) = arg.pat.simple_ident() {
90-
(
89+
let (error_var, span_label_var) = match arg.original_pat().simple_ident() {
90+
Some(simple_ident) => (
9191
format!("the type of `{}`", simple_ident),
9292
format!("the type of `{}`", simple_ident),
93-
)
94-
} else {
95-
("parameter type".to_owned(), "type".to_owned())
93+
),
94+
None => ("parameter type".to_owned(), "type".to_owned()),
9695
};
9796

9897
let mut diag = struct_span_err!(

src/librustc/middle/resolve_lifetime.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2420,7 +2420,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
24202420

24212421
let help_name = if let Some(body) = parent {
24222422
let arg = &self.tcx.hir().body(body).arguments[index];
2423-
format!("`{}`", self.tcx.hir().hir_to_pretty_string(arg.pat.hir_id))
2423+
format!("`{}`", self.tcx.hir().hir_to_pretty_string(arg.original_pat().hir_id))
24242424
} else {
24252425
format!("argument {}", index + 1)
24262426
};

src/librustc_typeck/check/writeback.rs

+6
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,12 @@ impl<'cx, 'gcx, 'tcx> Visitor<'gcx> for WritebackCx<'cx, 'gcx, 'tcx> {
297297
let ty = self.resolve(&ty, &hir_ty.span);
298298
self.write_ty_to_tables(hir_ty.hir_id, ty);
299299
}
300+
301+
fn visit_argument_source(&mut self, _: &'gcx hir::ArgSource) {
302+
// Don't visit the argument source, in `async fn`s it can contain a pattern which has a
303+
// `NodeId` w/out a type, as it is only used for getting the name of the original pattern
304+
// for diagnostics where only an `hir::Arg` is present.
305+
}
300306
}
301307

302308
impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {

src/libsyntax/ast.rs

+11
Original file line numberDiff line numberDiff line change
@@ -1724,6 +1724,16 @@ pub struct Arg {
17241724
pub ty: P<Ty>,
17251725
pub pat: P<Pat>,
17261726
pub id: NodeId,
1727+
pub source: ArgSource,
1728+
}
1729+
1730+
/// The source of an argument in a function header.
1731+
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
1732+
pub enum ArgSource {
1733+
/// Argument as written by the user.
1734+
Normal,
1735+
/// Argument from `async fn` lowering, contains the original binding pattern.
1736+
AsyncFn(P<Pat>),
17271737
}
17281738

17291739
/// Alternative representation for `Arg`s describing `self` parameter of methods.
@@ -1783,6 +1793,7 @@ impl Arg {
17831793
}),
17841794
ty,
17851795
id: DUMMY_NODE_ID,
1796+
source: ArgSource::Normal,
17861797
};
17871798
match eself.node {
17881799
SelfKind::Explicit(ty, mutbl) => arg(mutbl, ty),

src/libsyntax/ext/build.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -979,7 +979,8 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
979979
ast::Arg {
980980
ty,
981981
pat: arg_pat,
982-
id: ast::DUMMY_NODE_ID
982+
id: ast::DUMMY_NODE_ID,
983+
source: ast::ArgSource::Normal,
983984
}
984985
}
985986

src/libsyntax/mut_visit.rs

+13-1
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,10 @@ pub trait MutVisitor: Sized {
235235
noop_visit_arg(a, self);
236236
}
237237

238+
fn visit_arg_source(&mut self, a: &mut ArgSource) {
239+
noop_visit_arg_source(a, self);
240+
}
241+
238242
fn visit_generics(&mut self, generics: &mut Generics) {
239243
noop_visit_generics(generics, self);
240244
}
@@ -563,10 +567,18 @@ pub fn noop_visit_meta_item<T: MutVisitor>(mi: &mut MetaItem, vis: &mut T) {
563567
vis.visit_span(span);
564568
}
565569

566-
pub fn noop_visit_arg<T: MutVisitor>(Arg { id, pat, ty }: &mut Arg, vis: &mut T) {
570+
pub fn noop_visit_arg<T: MutVisitor>(Arg { id, pat, ty, source }: &mut Arg, vis: &mut T) {
567571
vis.visit_id(id);
568572
vis.visit_pat(pat);
569573
vis.visit_ty(ty);
574+
vis.visit_arg_source(source);
575+
}
576+
577+
pub fn noop_visit_arg_source<T: MutVisitor>(source: &mut ArgSource, vis: &mut T) {
578+
match source {
579+
ArgSource::Normal => {},
580+
ArgSource::AsyncFn(pat) => vis.visit_pat(pat),
581+
}
570582
}
571583

572584
pub fn noop_visit_tt<T: MutVisitor>(tt: &mut TokenTree, vis: &mut T) {

src/libsyntax/parse/parser.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::ast::{AngleBracketedArgs, AsyncArgument, ParenthesizedArgs, AttrStyle, BareFnTy};
22
use crate::ast::{GenericBound, TraitBoundModifier};
33
use crate::ast::Unsafety;
4-
use crate::ast::{Mod, AnonConst, Arg, Arm, Guard, Attribute, BindingMode, TraitItemKind};
4+
use crate::ast::{Mod, AnonConst, Arg, ArgSource, Arm, Guard, Attribute, BindingMode, TraitItemKind};
55
use crate::ast::Block;
66
use crate::ast::{BlockCheckMode, CaptureBy, Movability};
77
use crate::ast::{Constness, Crate};
@@ -550,7 +550,7 @@ fn dummy_arg(span: Span) -> Arg {
550550
span,
551551
id: ast::DUMMY_NODE_ID
552552
};
553-
Arg { ty: P(ty), pat: pat, id: ast::DUMMY_NODE_ID }
553+
Arg { ty: P(ty), pat: pat, id: ast::DUMMY_NODE_ID, source: ast::ArgSource::Normal }
554554
}
555555

556556
#[derive(Copy, Clone, Debug)]
@@ -2101,7 +2101,7 @@ impl<'a> Parser<'a> {
21012101
}
21022102
};
21032103

2104-
Ok(Arg { ty, pat, id: ast::DUMMY_NODE_ID })
2104+
Ok(Arg { ty, pat, id: ast::DUMMY_NODE_ID, source: ast::ArgSource::Normal })
21052105
}
21062106

21072107
/// Parses a single function argument.
@@ -2124,7 +2124,8 @@ impl<'a> Parser<'a> {
21242124
Ok(Arg {
21252125
ty: t,
21262126
pat,
2127-
id: ast::DUMMY_NODE_ID
2127+
id: ast::DUMMY_NODE_ID,
2128+
source: ast::ArgSource::Normal,
21282129
})
21292130
}
21302131

@@ -8689,6 +8690,7 @@ impl<'a> Parser<'a> {
86898690
),
86908691
span,
86918692
}),
8693+
source: ArgSource::AsyncFn(input.pat.clone()),
86928694
};
86938695

86948696
// Construct a `let <pat> = __argN;` statement to insert at the top of the

src/libsyntax/visit.rs

+3
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,9 @@ pub fn walk_fn_ret_ty<'a, V: Visitor<'a>>(visitor: &mut V, ret_ty: &'a FunctionR
534534
pub fn walk_fn_decl<'a, V: Visitor<'a>>(visitor: &mut V, function_declaration: &'a FnDecl) {
535535
for argument in &function_declaration.inputs {
536536
visitor.visit_pat(&argument.pat);
537+
if let ArgSource::AsyncFn(pat) = &argument.source {
538+
visitor.visit_pat(pat);
539+
}
537540
visitor.visit_ty(&argument.ty)
538541
}
539542
visitor.visit_fn_ret_ty(&function_declaration.output)

0 commit comments

Comments
 (0)